1 /* src/vm/jit/powerpc64/codegen.c - machine code generator for 32-bit PowerPC
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 $Id: codegen.c 5323 2006-09-05 16:45:24Z edwin $
49 #include "vm/jit/powerpc64/arch.h"
50 #include "vm/jit/powerpc64/codegen.h"
52 #include "mm/memory.h"
53 #include "native/native.h"
54 #include "vm/builtin.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/options.h"
59 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/codegen-common.h"
63 #include "vm/jit/dseg.h"
64 #include "vm/jit/emit.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/parse.h"
67 #include "vm/jit/patcher.h"
68 #include "vm/jit/reg.h"
69 #include "vm/jit/replace.h"
71 #if defined(ENABLE_LSRA)
72 # include "vm/jit/allocator/lsra.h"
76 /* codegen *********************************************************************
78 Generates machine code.
80 *******************************************************************************/
82 bool codegen(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
97 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
98 builtintable_entry *bte;
100 rplpoint *replacementpoint;
102 /* get required compiler data */
109 /* prevent compiler warnings */
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 stackframesize = rd->memuse + savedregs_num;
128 #if defined(ENABLE_THREADS)
129 /* space to save argument of monitor_enter and Return Values to survive */
130 /* monitor_exit. The stack position for the argument can not be shared */
131 /* with place to save the return register on PPC64, since both values */
133 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
134 /* reserve 2 slots for long/double return values for monitorexit */
140 /* create method header */
142 /* align stack to 16-bytes */
144 /* if (!m->isleafmethod || opt_verbosecall) */
145 stackframesize = (stackframesize + 3) & ~3;
147 /* else if (m->isleafmethod && (stackframesize == LA_WORD_SIZE)) */
148 /* stackframesize = 0; */
150 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
151 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
153 #if defined(ENABLE_THREADS)
154 /* IsSync contains the offset relative to the stack pointer for the
155 argument of monitor_exit used in the exception handler. Since the
156 offset could be zero and give a wrong meaning of the flag it is
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
164 (void) dseg_adds4(cd, 0); /* IsSync */
166 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
167 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
168 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170 dseg_addlinenumbertablesize(cd);
172 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
174 /* create exception table */
176 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
177 dseg_addtarget(cd, ex->start);
178 dseg_addtarget(cd, ex->end);
179 dseg_addtarget(cd, ex->handler);
180 (void) dseg_addaddress(cd, ex->catchtype.cls);
183 /* create stack frame (if necessary) */
185 if (!jd->isleafmethod) {
187 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
191 M_STDU(REG_SP, REG_SP, -stackframesize * 8);
193 /* save return address and used callee saved registers */
196 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
197 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
199 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
200 p --; M_DST(rd->savfltregs[i], REG_SP, p * 8);
203 /* take arguments out of register or stack frame */
207 for (p = 0, l = 0; p < md->paramcount; p++) {
208 t = md->paramtypes[p].type;
209 var = &(rd->locals[l][t]);
211 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
215 s1 = md->params[p].regoff;
216 if (IS_INT_LNG_TYPE(t)) { /* integer args */
217 if (IS_2_WORD_TYPE(t))
218 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
219 rd->argintregs[GET_HIGH_REG(s1)]);
221 s2 = rd->argintregs[s1];
222 if (!md->params[p].inmemory) { /* register arguments */
223 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
225 if (IS_2_WORD_TYPE(t)) /* FIXME, only M_INTMOVE here */
226 M_LNGMOVE(s2, var->regoff);
228 M_INTMOVE(s2, var->regoff);
230 } else { /* reg arg -> spilled */
231 if (IS_2_WORD_TYPE(t))
232 M_LST(s2, REG_SP, var->regoff * 4);
234 M_IST(s2, REG_SP, var->regoff * 4);
237 } else { /* stack arguments */
238 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
239 if (IS_2_WORD_TYPE(t))
240 M_LLD(var->regoff, REG_SP, (stackframesize + s1) * 4);
242 M_ILD(var->regoff, REG_SP, (stackframesize + s1) * 4);
244 } else { /* stack arg -> spilled */
246 M_ILD(REG_ITMP1, REG_SP, (stackframesize + s1) * 4);
247 M_IST(REG_ITMP1, REG_SP, var->regoff * 4);
248 if (IS_2_WORD_TYPE(t)) {
249 M_ILD(REG_ITMP1, REG_SP, (stackframesize + s1) * 4 +4);
250 M_IST(REG_ITMP1, REG_SP, var->regoff * 4 + 4);
253 /* Reuse Memory Position on Caller Stack */
254 var->regoff = stackframesize + s1;
259 } else { /* floating args */
260 if (!md->params[p].inmemory) { /* register arguments */
261 s2 = rd->argfltregs[s1];
262 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
263 M_FLTMOVE(s2, var->regoff);
265 } else { /* reg arg -> spilled */
266 if (IS_2_WORD_TYPE(t))
267 M_DST(s2, REG_SP, var->regoff * 4);
269 M_FST(s2, REG_SP, var->regoff * 4);
272 } else { /* stack arguments */
273 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
274 if (IS_2_WORD_TYPE(t))
275 M_DLD(var->regoff, REG_SP, (stackframesize + s1) * 4);
278 M_FLD(var->regoff, REG_SP, (stackframesize + s1) * 4);
280 } else { /* stack-arg -> spilled */
282 if (IS_2_WORD_TYPE(t)) {
283 M_DLD(REG_FTMP1, REG_SP, (stackframesize + s1) * 4);
284 M_DST(REG_FTMP1, REG_SP, var->regoff * 4);
285 var->regoff = stackframesize + s1;
288 M_FLD(REG_FTMP1, REG_SP, (stackframesize + s1) * 4);
289 M_FST(REG_FTMP1, REG_SP, var->regoff * 4);
292 /* Reuse Memory Position on Caller Stack */
293 var->regoff = stackframesize + s1;
300 /* save monitorenter argument */
302 #if defined(ENABLE_THREADS)
303 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
304 p = dseg_addaddress(cd, LOCK_monitor_enter);
305 M_ALD(REG_ITMP3, REG_PV, p);
306 M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
309 /* get or test the lock object */
311 if (m->flags & ACC_STATIC) {
312 p = dseg_addaddress(cd, &m->class->object.header);
313 M_ALD(rd->argintregs[0], REG_PV, p);
316 M_TST(rd->argintregs[0]);
318 codegen_add_nullpointerexception_ref(cd);
321 M_AST(rd->argintregs[0], REG_SP, rd->memuse * 8);
326 /* call trace function */
328 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
329 emit_verbosecall_enter(jd);
333 /* end of header generation */
335 replacementpoint = jd->code->rplpoints;
337 /* walk through all basic blocks */
338 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
340 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
342 if (bptr->flags >= BBREACHED) {
344 /* branch resolving */
348 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
349 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
355 /* handle replacement points */
357 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
358 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
363 /* copy interface registers to their destination */
369 #if defined(ENABLE_LSRA)
371 while (src != NULL) {
373 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
374 /* d = reg_of_var(m, src, REG_ITMP1); */
375 if (!(src->flags & INMEMORY))
379 M_INTMOVE(REG_ITMP1, d);
380 emit_store(jd, NULL, src, d);
386 while (src != NULL) {
388 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
389 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
390 M_INTMOVE(REG_ITMP1, d);
391 emit_store(jd, NULL, src, d);
393 if (src->type == TYPE_LNG)
394 d = codegen_reg_of_var(rd, 0, src, PACK_REGS(REG_ITMP2, REG_ITMP1));
396 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
397 if ((src->varkind != STACKVAR)) {
399 if (IS_FLT_DBL_TYPE(s2)) {
400 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
401 s1 = rd->interfaces[len][s2].regoff;
404 if (IS_2_WORD_TYPE(s2)) {
406 rd->interfaces[len][s2].regoff * 4);
409 rd->interfaces[len][s2].regoff * 4);
413 emit_store(jd, NULL, src, d);
416 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
417 s1 = rd->interfaces[len][s2].regoff;
418 if (IS_2_WORD_TYPE(s2))
423 if (IS_2_WORD_TYPE(s2))
425 rd->interfaces[len][s2].regoff * 4);
428 rd->interfaces[len][s2].regoff * 4);
431 emit_store(jd, NULL, src, d);
438 #if defined(ENABLE_LSRA)
441 /* walk through all instructions */
447 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
448 if (iptr->line != currentline) {
449 dseg_addlinenumber(cd, iptr->line);
450 currentline = iptr->line;
453 MCODECHECK(64); /* an instruction usually needs < 64 words */
455 M_NOP; M_NOP; /* XXX */
457 case ICMD_NOP: /* ... ==> ... */
458 case ICMD_INLINE_START:
459 case ICMD_INLINE_END:
462 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
464 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
467 codegen_add_nullpointerexception_ref(cd);
470 /* constant operations ************************************************/
472 case ICMD_ICONST: /* ... ==> ..., constant */
473 /* op1 = 0, val.i = constant */
475 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
476 ICONST(d, iptr->val.i);
477 emit_store(jd, iptr, iptr->dst, d);
480 case ICMD_LCONST: /* ... ==> ..., constant */
481 /* op1 = 0, val.l = constant */
483 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
484 LCONST(d, iptr->val.l);
485 emit_store(jd, iptr, iptr->dst, d);
488 case ICMD_FCONST: /* ... ==> ..., constant */
489 /* op1 = 0, val.f = constant */
491 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
492 a = dseg_addfloat(cd, iptr->val.f);
494 emit_store(jd, iptr, iptr->dst, d);
497 case ICMD_DCONST: /* ... ==> ..., constant */
498 /* op1 = 0, val.d = constant */
500 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
501 a = dseg_adddouble(cd, iptr->val.d);
503 emit_store(jd, iptr, iptr->dst, d);
506 case ICMD_ACONST: /* ... ==> ..., constant */
507 /* op1 = 0, val.a = constant */
508 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
509 disp = dseg_addaddress(cd, iptr->val.a);
511 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
512 codegen_addpatchref(cd, PATCHER_aconst,
513 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
516 if (opt_showdisassemble)
520 M_ALD(d, REG_PV, disp);
521 emit_store(jd, iptr, iptr->dst, d);
525 /* load/store operations **********************************************/
527 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
529 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
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 if (var->flags & INMEMORY)
535 M_ILD(d, REG_SP, var->regoff * 4);
537 M_INTMOVE(var->regoff, d);
538 emit_store(jd, iptr, iptr->dst, d);
541 case ICMD_ALOAD: /* op1 = local variable */
542 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
543 /* op1 = local variable */
545 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
546 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
547 if ((iptr->dst->varkind == LOCALVAR) &&
548 (iptr->dst->varnum == iptr->op1))
550 if (var->flags & INMEMORY)
551 M_LLD(d, REG_SP, var->regoff * 4);
553 M_LNGMOVE(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 * 4);
568 M_FLTMOVE(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 * 4);
583 M_FLTMOVE(var->regoff, d);
584 emit_store(jd, iptr, iptr->dst, d);
588 case ICMD_ISTORE: /* ..., value ==> ... */
589 case ICMD_ASTORE: /* op1 = local variable */
591 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
593 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
594 if (var->flags & INMEMORY) {
595 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
596 M_IST(s1, REG_SP, var->regoff * 4);
598 s1 = emit_load_s1(jd, iptr, src, var->regoff);
599 M_INTMOVE(s1, var->regoff);
603 case ICMD_LSTORE: /* ..., value ==> ... */
604 /* op1 = local variable */
606 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
608 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
609 if (var->flags & INMEMORY) {
610 s1 = emit_load_s1(jd, iptr, src, PACK_REGS(REG_ITMP2, REG_ITMP1));
611 M_LST(s1, REG_SP, var->regoff * 4);
613 s1 = emit_load_s1(jd, iptr, src, var->regoff);
614 M_LNGMOVE(s1, var->regoff);
618 case ICMD_FSTORE: /* ..., value ==> ... */
619 /* op1 = local variable */
621 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
623 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
624 if (var->flags & INMEMORY) {
625 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
626 M_FST(s1, REG_SP, var->regoff * 4);
628 s1 = emit_load_s1(jd, iptr, src, var->regoff);
629 M_FLTMOVE(s1, var->regoff);
633 case ICMD_DSTORE: /* ..., value ==> ... */
634 /* op1 = local variable */
636 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
638 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
639 if (var->flags & INMEMORY) {
640 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
641 M_DST(s1, REG_SP, var->regoff * 4);
643 s1 = emit_load_s1(jd, iptr, src, var->regoff);
644 M_FLTMOVE(s1, var->regoff);
649 /* pop/dup/swap operations ********************************************/
651 /* attention: double and longs are only one entry in CACAO ICMDs */
653 case ICMD_POP: /* ..., value ==> ... */
654 case ICMD_POP2: /* ..., value, value ==> ... */
657 case ICMD_DUP: /* ..., a ==> ..., a, a */
658 M_COPY(src, iptr->dst);
661 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
663 M_COPY(src, iptr->dst);
664 M_COPY(src->prev, iptr->dst->prev);
665 M_COPY(iptr->dst, iptr->dst->prev->prev);
668 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
670 M_COPY(src, iptr->dst);
671 M_COPY(src->prev, iptr->dst->prev);
672 M_COPY(src->prev->prev, iptr->dst->prev->prev);
673 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
676 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
678 M_COPY(src, iptr->dst);
679 M_COPY(src->prev, iptr->dst->prev);
682 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
684 M_COPY(src, iptr->dst);
685 M_COPY(src->prev, iptr->dst->prev);
686 M_COPY(src->prev->prev, iptr->dst->prev->prev);
687 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
688 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
691 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
693 M_COPY(src, iptr->dst);
694 M_COPY(src->prev, iptr->dst->prev);
695 M_COPY(src->prev->prev, iptr->dst->prev->prev);
696 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
697 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
698 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
701 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
703 M_COPY(src, iptr->dst->prev);
704 M_COPY(src->prev, iptr->dst);
708 /* integer operations *************************************************/
710 case ICMD_INEG: /* ..., value ==> ..., - value */
712 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
713 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
715 emit_store(jd, iptr, iptr->dst, d);
718 case ICMD_LNEG: /* ..., value ==> ..., - value */
720 s1 = emit_load_s1(jd, iptr, src, PACK_REGS(REG_ITMP2, REG_ITMP1));
721 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
722 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
723 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
724 emit_store(jd, iptr, iptr->dst, d);
727 case ICMD_I2L: /* ..., value ==> ..., value */
729 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
730 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
731 M_INTMOVE(s1, GET_LOW_REG(d));
732 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
733 emit_store(jd, iptr, iptr->dst, d);
736 case ICMD_L2I: /* ..., value ==> ..., value */
738 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP2);
739 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
741 emit_store(jd, iptr, iptr->dst, d);
744 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
746 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
747 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
749 emit_store(jd, iptr, iptr->dst, d);
752 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
754 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
755 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
757 emit_store(jd, iptr, iptr->dst, d);
760 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
762 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
763 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
765 emit_store(jd, iptr, iptr->dst, d);
769 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
771 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
772 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
773 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
775 emit_store(jd, iptr, iptr->dst, d);
778 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
779 /* val.i = constant */
781 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
782 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
783 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
784 M_IADD_IMM(s1, iptr->val.i, d);
786 ICONST(REG_ITMP2, iptr->val.i);
787 M_IADD(s1, REG_ITMP2, d);
789 emit_store(jd, iptr, iptr->dst, d);
792 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
794 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
795 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
796 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
797 M_ADDC(s1, s2, GET_LOW_REG(d));
798 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
799 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
800 M_ADDE(s1, s2, GET_HIGH_REG(d));
801 emit_store(jd, iptr, iptr->dst, d);
804 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
805 /* val.l = constant */
807 s3 = iptr->val.l & 0xffffffff;
808 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
809 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
810 if ((s3 >= -32768) && (s3 <= 32767)) {
811 M_ADDIC(s1, s3, GET_LOW_REG(d));
813 ICONST(REG_ITMP2, s3);
814 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
816 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
817 s3 = iptr->val.l >> 32;
819 M_ADDME(s1, GET_HIGH_REG(d));
820 } else if (s3 == 0) {
821 M_ADDZE(s1, GET_HIGH_REG(d));
823 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
824 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
826 emit_store(jd, iptr, iptr->dst, d);
829 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
831 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
832 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
833 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
835 emit_store(jd, iptr, iptr->dst, d);
838 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
839 /* val.i = constant */
841 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
842 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
843 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
844 M_IADD_IMM(s1, -iptr->val.i, d);
846 ICONST(REG_ITMP2, -iptr->val.i);
847 M_IADD(s1, REG_ITMP2, d);
849 emit_store(jd, iptr, iptr->dst, d);
852 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
854 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
855 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
856 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
857 M_SUBC(s1, s2, GET_LOW_REG(d));
858 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
859 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
860 M_SUBE(s1, s2, GET_HIGH_REG(d));
861 emit_store(jd, iptr, iptr->dst, d);
864 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
865 /* val.l = constant */
867 s3 = (-iptr->val.l) & 0xffffffff;
868 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
869 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
870 if ((s3 >= -32768) && (s3 <= 32767)) {
871 M_ADDIC(s1, s3, GET_LOW_REG(d));
873 ICONST(REG_ITMP2, s3);
874 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
876 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
877 s3 = (-iptr->val.l) >> 32;
879 M_ADDME(s1, GET_HIGH_REG(d));
881 M_ADDZE(s1, GET_HIGH_REG(d));
883 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
884 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
886 emit_store(jd, iptr, iptr->dst, d);
889 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
891 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
892 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
893 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
896 codegen_add_arithmeticexception_ref(cd);
897 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
898 M_CMP(REG_ITMP3, s1);
899 M_BNE(3 + (s1 != d));
901 M_BNE(1 + (s1 != d));
905 emit_store(jd, iptr, iptr->dst, d);
908 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
910 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
911 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
912 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
915 codegen_add_arithmeticexception_ref(cd);
916 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
917 M_CMP(REG_ITMP3, s1);
923 M_IDIV(s1, s2, REG_ITMP3);
924 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
925 M_ISUB(s1, REG_ITMP3, d);
926 emit_store(jd, iptr, iptr->dst, d);
929 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
930 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
935 s2 = emit_load_s2(jd, iptr, src, PACK_REGS(REG_ITMP2, REG_ITMP1));
936 M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
938 codegen_add_arithmeticexception_ref(cd);
940 disp = dseg_addaddress(cd, bte->fp);
941 M_ALD(REG_ITMP3, REG_PV, disp);
944 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
945 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
948 s1 = emit_load_s1(jd, iptr, src->prev, PACK_REGS(REG_ITMP2, REG_ITMP1));
949 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
950 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
955 /*d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_RESULT2, REG_RESULT)); //FIXME */
956 /*M_LNGMOVE(PACK_REGS(REG_RESULT2, REG_RESULT), d); FIXME*/
957 emit_store(jd, iptr, iptr->dst, d);
960 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
962 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
963 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
964 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
966 emit_store(jd, iptr, iptr->dst, d);
969 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
970 /* val.i = constant */
972 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
973 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
974 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
975 M_IMUL_IMM(s1, iptr->val.i, d);
977 ICONST(REG_ITMP3, iptr->val.i);
978 M_IMUL(s1, REG_ITMP3, d);
980 emit_store(jd, iptr, iptr->dst, d);
983 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
985 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
986 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
987 M_SRA_IMM(s1, iptr->val.i, d);
989 emit_store(jd, iptr, iptr->dst, d);
992 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
994 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
995 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
996 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
997 M_AND_IMM(s2, 0x1f, REG_ITMP3);
998 M_SLL(s1, REG_ITMP3, d);
999 emit_store(jd, iptr, iptr->dst, d);
1002 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1003 /* val.i = constant */
1005 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1006 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1007 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1008 emit_store(jd, iptr, iptr->dst, d);
1011 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1013 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1014 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1015 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1016 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1017 M_SRA(s1, REG_ITMP3, d);
1018 emit_store(jd, iptr, iptr->dst, d);
1021 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1022 /* val.i = constant */
1024 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1025 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1026 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1027 emit_store(jd, iptr, iptr->dst, d);
1030 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1032 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1033 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1034 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1035 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1036 M_SRL(s1, REG_ITMP2, d);
1037 emit_store(jd, iptr, iptr->dst, d);
1040 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1041 /* val.i = constant */
1043 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1044 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1045 if (iptr->val.i & 0x1f) {
1046 M_SRL_IMM(s1, iptr->val.i & 0x1f, d);
1050 emit_store(jd, iptr, iptr->dst, d);
1053 case ICMD_IAND: /* ..., 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_IANDCONST: /* ..., 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 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1068 M_AND_IMM(s1, iptr->val.i, d);
1071 else if (iptr->val.i == 0xffffff) {
1072 M_RLWINM(s1, 0, 8, 31, d);
1076 ICONST(REG_ITMP3, iptr->val.i);
1077 M_AND(s1, REG_ITMP3, d);
1079 emit_store(jd, iptr, iptr->dst, d);
1082 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1084 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1085 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1086 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1087 M_AND(s1, s2, GET_LOW_REG(d));
1088 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
1089 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
1090 M_AND(s1, s2, GET_HIGH_REG(d));
1091 emit_store(jd, iptr, iptr->dst, d);
1094 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1095 /* val.l = constant */
1097 s3 = iptr->val.l & 0xffffffff;
1098 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
1099 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1100 if ((s3 >= 0) && (s3 <= 65535)) {
1101 M_AND_IMM(s1, s3, GET_LOW_REG(d));
1103 ICONST(REG_ITMP3, s3);
1104 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
1106 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
1107 s3 = iptr->val.l >> 32;
1108 if ((s3 >= 0) && (s3 <= 65535)) {
1109 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
1111 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1112 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
1114 emit_store(jd, iptr, iptr->dst, d);
1117 case ICMD_IREMPOW2: /* ..., 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 M_MOV(s1, REG_ITMP2);
1124 M_BGE(1 + 2*(iptr->val.i >= 32768));
1125 if (iptr->val.i >= 32768) {
1126 M_ADDIS(REG_ZERO, iptr->val.i >> 16, REG_ITMP2);
1127 M_OR_IMM(REG_ITMP2, iptr->val.i, REG_ITMP2);
1128 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1130 M_IADD_IMM(s1, iptr->val.i, REG_ITMP2);
1133 int b=0, m = iptr->val.i;
1136 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1138 M_ISUB(s1, REG_ITMP2, d);
1139 emit_store(jd, iptr, iptr->dst, d);
1142 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1144 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1145 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1146 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1148 emit_store(jd, iptr, iptr->dst, d);
1151 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1152 /* val.i = constant */
1154 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1155 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1156 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1157 M_OR_IMM(s1, iptr->val.i, d);
1159 ICONST(REG_ITMP3, iptr->val.i);
1160 M_OR(s1, REG_ITMP3, d);
1162 emit_store(jd, iptr, iptr->dst, d);
1165 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1167 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1168 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1169 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1170 M_OR(s1, s2, GET_LOW_REG(d));
1171 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
1172 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
1173 M_OR(s1, s2, GET_HIGH_REG(d));
1174 emit_store(jd, iptr, iptr->dst, d);
1177 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1178 /* val.l = constant */
1180 s3 = iptr->val.l & 0xffffffff;
1181 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
1182 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1183 if ((s3 >= 0) && (s3 <= 65535)) {
1184 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1186 ICONST(REG_ITMP3, s3);
1187 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1189 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
1190 s3 = iptr->val.l >> 32;
1191 if ((s3 >= 0) && (s3 <= 65535)) {
1192 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1194 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1195 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1197 emit_store(jd, iptr, iptr->dst, d);
1200 case ICMD_IXOR: /* ..., 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_IXORCONST: /* ..., 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 <= 65535)) {
1215 M_XOR_IMM(s1, iptr->val.i, d);
1217 ICONST(REG_ITMP3, iptr->val.i);
1218 M_XOR(s1, REG_ITMP3, d);
1220 emit_store(jd, iptr, iptr->dst, d);
1223 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1225 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1226 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1227 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1228 M_XOR(s1, s2, GET_LOW_REG(d));
1229 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
1230 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
1231 M_XOR(s1, s2, GET_HIGH_REG(d));
1232 emit_store(jd, iptr, iptr->dst, d);
1235 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1236 /* val.l = constant */
1238 s3 = iptr->val.l & 0xffffffff;
1239 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
1240 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1241 if ((s3 >= 0) && (s3 <= 65535)) {
1242 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1244 ICONST(REG_ITMP3, s3);
1245 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1247 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
1248 s3 = iptr->val.l >> 32;
1249 if ((s3 >= 0) && (s3 <= 65535)) {
1250 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1252 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1253 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1255 emit_store(jd, iptr, iptr->dst, d);
1258 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1259 /*******************************************************************
1260 TODO: CHANGE THIS TO A VERSION THAT WORKS !!!
1261 *******************************************************************/
1262 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP3);
1263 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
1264 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1266 int tempreg = false;
1270 if (src->prev->flags & INMEMORY) {
1271 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1273 tempreg = tempreg || (d == GET_HIGH_REG(src->prev->regoff))
1274 || (d == GET_LOW_REG(src->prev->regoff));
1276 if (src->flags & INMEMORY) {
1277 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1279 tempreg = tempreg || (d == GET_HIGH_REG(src->regoff))
1280 || (d == GET_LOW_REG(src->regoff));
1283 dreg = tempreg ? REG_ITMP1 : d;
1284 M_IADD_IMM(REG_ZERO, 1, dreg);
1289 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP3);
1290 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1294 M_IADD_IMM(dreg, -1, dreg);
1295 M_IADD_IMM(dreg, -1, dreg);
1296 gen_resolvebranch(br1, br1, cd->mcodeptr);
1297 gen_resolvebranch(br1 + 1 * 4, br1 + 1 * 4, cd->mcodeptr - 2 * 4);
1300 emit_store(jd, iptr, iptr->dst, d);
1303 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1304 /* op1 = variable, val.i = constant */
1306 var = &(rd->locals[iptr->op1][TYPE_INT]);
1307 if (var->flags & INMEMORY) {
1309 M_ILD(s1, REG_SP, var->regoff * 4);
1317 M_ADDIS(s1, m >> 16, s1);
1319 M_IADD_IMM(s1, m & 0xffff, s1);
1321 if (var->flags & INMEMORY)
1322 M_IST(s1, REG_SP, var->regoff * 4);
1326 /* floating operations ************************************************/
1328 case ICMD_FNEG: /* ..., value ==> ..., - value */
1330 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1331 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1333 emit_store(jd, iptr, iptr->dst, d);
1336 case ICMD_DNEG: /* ..., value ==> ..., - value */
1338 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1339 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1341 emit_store(jd, iptr, iptr->dst, d);
1344 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1346 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1347 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1348 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1350 emit_store(jd, iptr, iptr->dst, d);
1353 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1355 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1356 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1357 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1359 emit_store(jd, iptr, iptr->dst, d);
1362 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1364 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1365 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1366 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1368 emit_store(jd, iptr, iptr->dst, d);
1371 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1373 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1374 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1375 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1377 emit_store(jd, iptr, iptr->dst, d);
1380 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1382 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1383 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1384 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1386 emit_store(jd, iptr, iptr->dst, d);
1389 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1391 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1392 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1393 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1395 emit_store(jd, iptr, iptr->dst, d);
1398 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1400 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1401 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1402 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1404 emit_store(jd, iptr, iptr->dst, d);
1407 case ICMD_DDIV: /* ..., 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);
1413 emit_store(jd, iptr, iptr->dst, d);
1416 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1419 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1420 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1422 disp = dseg_addfloat(cd, 0.0);
1423 M_FLD(REG_FTMP2, REG_PV, disp);
1424 M_FCMPU(s1, REG_FTMP2);
1426 disp = dseg_adds4(cd, 0);
1427 M_CVTDL_C(s1, REG_FTMP1);
1428 M_LDA(REG_ITMP1, REG_PV, disp);
1429 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1430 M_ILD(d, REG_PV, disp);
1431 emit_store(jd, iptr, iptr->dst, d);
1434 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1436 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1437 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1439 emit_store(jd, iptr, iptr->dst, d);
1442 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1444 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1445 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1447 emit_store(jd, iptr, iptr->dst, d);
1450 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1451 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1454 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1455 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1456 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1458 M_IADD_IMM(REG_ZERO, -1, d);
1461 M_IADD_IMM(REG_ZERO, 0, d);
1463 M_IADD_IMM(REG_ZERO, 1, d);
1464 emit_store(jd, iptr, iptr->dst, d);
1467 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1468 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1470 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1471 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1472 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1474 M_IADD_IMM(REG_ZERO, 1, d);
1477 M_IADD_IMM(REG_ZERO, 0, d);
1479 M_IADD_IMM(REG_ZERO, -1, d);
1480 emit_store(jd, iptr, iptr->dst, d);
1483 case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */
1484 case ICMD_IF_DCMPEQ:
1486 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1487 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1491 codegen_addreference(cd, (basicblock *) iptr->target);
1494 case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */
1495 case ICMD_IF_DCMPNE:
1497 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1498 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1501 codegen_addreference(cd, (basicblock *) iptr->target);
1503 codegen_addreference(cd, (basicblock *) iptr->target);
1507 case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */
1508 case ICMD_IF_DCMPL_LT:
1510 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1511 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1514 codegen_addreference(cd, (basicblock *) iptr->target);
1516 codegen_addreference(cd, (basicblock *) iptr->target);
1519 case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */
1520 case ICMD_IF_DCMPL_GT:
1522 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1523 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1527 codegen_addreference(cd, (basicblock *) iptr->target);
1530 case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */
1531 case ICMD_IF_DCMPL_LE:
1533 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1534 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1537 codegen_addreference(cd, (basicblock *) iptr->target);
1539 codegen_addreference(cd, (basicblock *) iptr->target);
1542 case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */
1543 case ICMD_IF_DCMPL_GE:
1545 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1546 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1550 codegen_addreference(cd, (basicblock *) iptr->target);
1553 case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */
1554 case ICMD_IF_DCMPG_LT:
1556 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1557 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1561 codegen_addreference(cd, (basicblock *) iptr->target);
1564 case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */
1565 case ICMD_IF_DCMPG_GT:
1567 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1568 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1571 codegen_addreference(cd, (basicblock *) iptr->target);
1573 codegen_addreference(cd, (basicblock *) iptr->target);
1576 case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */
1577 case ICMD_IF_DCMPG_LE:
1579 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1580 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1584 codegen_addreference(cd, (basicblock *) iptr->target);
1587 case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */
1588 case ICMD_IF_DCMPG_GE:
1590 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1591 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1594 codegen_addreference(cd, (basicblock *) iptr->target);
1596 codegen_addreference(cd, (basicblock *) iptr->target);
1600 /* memory operations **************************************************/
1602 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1604 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1605 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1606 gen_nullptr_check(s1);
1607 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1608 emit_store(jd, iptr, iptr->dst, d);
1611 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1613 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1614 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1615 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1616 if (iptr->op1 == 0) {
1617 gen_nullptr_check(s1);
1620 M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1621 M_LBZX(d, s1, REG_ITMP2);
1623 emit_store(jd, iptr, iptr->dst, d);
1626 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1628 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1629 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1630 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1631 if (iptr->op1 == 0) {
1632 gen_nullptr_check(s1);
1635 M_SLL_IMM(s2, 1, REG_ITMP2);
1636 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1637 M_LHZX(d, s1, REG_ITMP2);
1638 emit_store(jd, iptr, iptr->dst, d);
1641 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1643 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1644 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1645 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1646 if (iptr->op1 == 0) {
1647 gen_nullptr_check(s1);
1650 M_SLL_IMM(s2, 1, REG_ITMP2);
1651 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1652 M_LHAX(d, s1, REG_ITMP2);
1653 emit_store(jd, iptr, iptr->dst, d);
1656 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1658 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1659 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1660 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1661 if (iptr->op1 == 0) {
1662 gen_nullptr_check(s1);
1665 M_SLL_IMM(s2, 2, REG_ITMP2);
1666 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1667 M_LWZX(d, s1, REG_ITMP2);
1668 emit_store(jd, iptr, iptr->dst, d);
1671 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1673 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1674 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1675 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1676 if (iptr->op1 == 0) {
1677 gen_nullptr_check(s1);
1680 M_SLL_IMM(s2, 3, REG_ITMP2);
1681 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1682 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1683 emit_store(jd, iptr, iptr->dst, d);
1686 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1688 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1689 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1690 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1691 if (iptr->op1 == 0) {
1692 gen_nullptr_check(s1);
1695 M_SLL_IMM(s2, 2, REG_ITMP2);
1696 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1697 M_LFSX(d, s1, REG_ITMP2);
1698 emit_store(jd, iptr, iptr->dst, d);
1701 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1703 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1704 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1705 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1706 if (iptr->op1 == 0) {
1707 gen_nullptr_check(s1);
1710 M_SLL_IMM(s2, 3, REG_ITMP2);
1711 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1712 M_LFDX(d, s1, REG_ITMP2);
1713 emit_store(jd, iptr, iptr->dst, d);
1716 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1718 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1719 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1720 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1721 if (iptr->op1 == 0) {
1722 gen_nullptr_check(s1);
1725 M_SLL_IMM(s2, 2, REG_ITMP2);
1726 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1727 M_LWZX(d, s1, REG_ITMP2);
1728 emit_store(jd, iptr, iptr->dst, d);
1732 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1734 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1736 if (iptr->op1 == 0) {
1737 gen_nullptr_check(s1);
1740 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1741 M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1742 M_STBX(s3, s1, REG_ITMP2);
1745 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1747 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1748 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1749 if (iptr->op1 == 0) {
1750 gen_nullptr_check(s1);
1753 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1754 M_SLL_IMM(s2, 1, REG_ITMP2);
1755 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1756 M_STHX(s3, s1, REG_ITMP2);
1759 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1761 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1762 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1763 if (iptr->op1 == 0) {
1764 gen_nullptr_check(s1);
1767 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1768 M_SLL_IMM(s2, 1, REG_ITMP2);
1769 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1770 M_STHX(s3, s1, REG_ITMP2);
1773 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1775 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1776 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1777 if (iptr->op1 == 0) {
1778 gen_nullptr_check(s1);
1781 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1782 M_SLL_IMM(s2, 2, REG_ITMP2);
1783 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1784 M_STWX(s3, s1, REG_ITMP2);
1787 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1789 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1790 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1791 if (iptr->op1 == 0) {
1792 gen_nullptr_check(s1);
1795 s3 = emit_load_s3_high(jd, iptr, src, REG_ITMP3);
1796 M_SLL_IMM(s2, 3, REG_ITMP2);
1797 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
1798 M_STWX(s3, s1, REG_ITMP2);
1799 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1800 s3 = emit_load_s3_low(jd, iptr, src, REG_ITMP3);
1801 M_STWX(s3, s1, REG_ITMP2);
1804 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1806 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1807 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1808 if (iptr->op1 == 0) {
1809 gen_nullptr_check(s1);
1812 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1813 M_SLL_IMM(s2, 2, REG_ITMP2);
1814 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1815 M_STFSX(s3, s1, REG_ITMP2);
1818 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1820 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1821 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1822 if (iptr->op1 == 0) {
1823 gen_nullptr_check(s1);
1826 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1827 M_SLL_IMM(s2, 3, REG_ITMP2);
1828 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1829 M_STFDX(s3, s1, REG_ITMP2);
1832 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1834 s1 = emit_load_s1(jd, iptr, src->prev->prev, rd->argintregs[0]);
1835 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1836 if (iptr->op1 == 0) {
1837 gen_nullptr_check(s1);
1840 s3 = emit_load_s3(jd, iptr, src, rd->argintregs[1]);
1842 disp = dseg_addaddress(cd, BUILTIN_canstore);
1843 M_ALD(REG_ITMP3, REG_PV, disp);
1844 M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
1847 M_INTMOVE(s1, rd->argintregs[0]);
1848 M_INTMOVE(s3, rd->argintregs[1]);
1853 codegen_add_arraystoreexception_ref(cd);
1855 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1856 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1857 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1858 M_SLL_IMM(s2, 2, REG_ITMP2);
1859 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1860 M_STWX(s3, s1, REG_ITMP2);
1864 case ICMD_GETSTATIC: /* ... ==> ..., value */
1865 /* op1 = type, val.a = field address */
1867 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1868 disp = dseg_addaddress(cd, NULL);
1870 codegen_addpatchref(cd, PATCHER_get_putstatic,
1871 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1873 if (opt_showdisassemble)
1877 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1879 disp = dseg_addaddress(cd, &(fi->value));
1881 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1882 codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
1884 if (opt_showdisassemble)
1889 M_ALD(REG_ITMP1, REG_PV, disp);
1890 switch (iptr->op1) {
1892 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1893 M_ILD_INTERN(d, REG_ITMP1, 0);
1896 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, PACK_REGS(REG_ITMP2, REG_ITMP1));
1897 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1898 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1901 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1902 M_ALD_INTERN(d, REG_ITMP1, 0);
1905 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1906 M_FLD_INTERN(d, REG_ITMP1, 0);
1909 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1910 M_DLD_INTERN(d, REG_ITMP1, 0);
1913 emit_store(jd, iptr, iptr->dst, d);
1916 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1917 /* op1 = type, val.a = field address */
1920 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1921 disp = dseg_addaddress(cd, NULL);
1923 codegen_addpatchref(cd, PATCHER_get_putstatic,
1924 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1926 if (opt_showdisassemble)
1930 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1932 disp = dseg_addaddress(cd, &(fi->value));
1934 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1935 codegen_addpatchref(cd, PATCHER_clinit, fi->class, disp);
1937 if (opt_showdisassemble)
1942 M_ALD(REG_ITMP1, REG_PV, disp);
1943 switch (iptr->op1) {
1945 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1946 M_IST_INTERN(s1, REG_ITMP1, 0);
1949 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1950 M_LST_INTERN(s1, REG_ITMP1, 0);
1953 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1954 M_AST_INTERN(s1, REG_ITMP1, 0);
1957 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1958 M_FST_INTERN(s1, REG_ITMP1, 0);
1961 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1962 M_DST_INTERN(s1, REG_ITMP1, 0);
1968 case ICMD_GETFIELD: /* ... ==> ..., value */
1969 /* op1 = type, val.i = field offset */
1971 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1972 gen_nullptr_check(s1);
1974 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1975 codegen_addpatchref(cd, PATCHER_get_putfield,
1976 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
1978 if (opt_showdisassemble)
1984 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
1987 switch (iptr->op1) {
1989 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1993 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1997 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2001 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2005 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2009 emit_store(jd, iptr, iptr->dst, d);
2012 case ICMD_PUTFIELD: /* ..., value ==> ... */
2013 /* op1 = type, val.i = field offset */
2015 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2016 gen_nullptr_check(s1);
2018 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2019 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2021 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2024 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2025 codegen_addpatchref(cd, PATCHER_get_putfield,
2026 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2028 if (opt_showdisassemble)
2034 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2037 switch (iptr->op1) {
2039 M_IST(s2, s1, disp);
2042 M_LST(s2, s1, disp);
2045 M_AST(s2, s1, disp);
2048 M_FST(s2, s1, disp);
2051 M_DST(s2, s1, disp);
2057 /* branch operations **************************************************/
2059 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2061 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2062 M_LNGMOVE(s1, REG_ITMP1_XPTR);
2064 #ifdef ENABLE_VERIFIER
2066 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2067 (unresolved_class *) iptr->val.a, 0);
2069 if (opt_showdisassemble)
2072 #endif /* ENABLE_VERIFIER */
2074 disp = dseg_addaddress(cd, asm_handle_exception);
2075 M_ALD(REG_ITMP2, REG_PV, disp);
2078 if (jd->isleafmethod) M_MFLR(REG_ITMP3); /* save LR */
2079 M_BL(0); /* get current PC */
2080 M_MFLR(REG_ITMP2_XPC);
2081 if (jd->isleafmethod) M_MTLR(REG_ITMP3); /* restore LR */
2082 M_RTS; /* jump to CTR */
2087 case ICMD_GOTO: /* ... ==> ... */
2088 /* op1 = target JavaVM pc */
2090 codegen_addreference(cd, (basicblock *) iptr->target);
2094 case ICMD_JSR: /* ... ==> ... */
2095 /* op1 = target JavaVM pc */
2097 if (jd->isleafmethod)
2101 M_IADD_IMM(REG_ITMP1, jd->isleafmethod ? 4*4 : 3*4, REG_ITMP1);
2102 if (jd->isleafmethod)
2105 codegen_addreference(cd, (basicblock *) iptr->target);
2108 case ICMD_RET: /* ... ==> ... */
2109 /* op1 = local variable */
2111 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2112 if (var->flags & INMEMORY) {
2113 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2116 M_MTCTR(var->regoff);
2122 case ICMD_IFNULL: /* ..., value ==> ... */
2123 /* op1 = target JavaVM pc */
2125 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2128 codegen_addreference(cd, (basicblock *) iptr->target);
2131 case ICMD_IFNONNULL: /* ..., value ==> ... */
2132 /* op1 = target JavaVM pc */
2134 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2137 codegen_addreference(cd, (basicblock *) iptr->target);
2145 case ICMD_IFEQ: /* ..., value ==> ... */
2146 /* op1 = target JavaVM pc, val.i = constant */
2148 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2149 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767))
2150 M_CMPI(s1, iptr->val.i);
2152 ICONST(REG_ITMP2, iptr->val.i);
2153 M_CMP(s1, REG_ITMP2);
2155 switch (iptr->opc) {
2175 codegen_addreference(cd, (basicblock *) iptr->target);
2179 case ICMD_IF_LEQ: /* ..., value ==> ... */
2180 /* op1 = target JavaVM pc, val.l = constant */
2182 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2183 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2184 if (iptr->val.l == 0) {
2185 M_OR_TST(s1, s2, REG_ITMP3);
2186 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2187 M_XOR_IMM(s2, 0, REG_ITMP2);
2188 M_XOR_IMM(s1, iptr->val.l & 0xffff, REG_ITMP1);
2189 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2191 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2192 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2193 ICONST(REG_ITMP3, iptr->val.l >> 32);
2194 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2195 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2198 codegen_addreference(cd, (basicblock *) iptr->target);
2201 case ICMD_IF_LLT: /* ..., value ==> ... */
2202 /* op1 = target JavaVM pc, val.l = constant */
2203 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2204 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2205 if (iptr->val.l == 0) {
2206 /* if high word is less than zero, the whole long is too */
2208 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2211 codegen_addreference(cd, (basicblock *) iptr->target);
2213 M_CMPUI(s1, iptr->val.l & 0xffff);
2215 ICONST(REG_ITMP3, iptr->val.l >> 32);
2216 M_CMP(s2, REG_ITMP3);
2218 codegen_addreference(cd, (basicblock *) iptr->target);
2220 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2221 M_CMPU(s1, REG_ITMP3);
2224 codegen_addreference(cd, (basicblock *) iptr->target);
2227 case ICMD_IF_LLE: /* ..., value ==> ... */
2228 /* op1 = target JavaVM pc, val.l = constant */
2230 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2231 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2232 /* if (iptr->val.l == 0) { */
2233 /* M_OR(s1, s2, REG_ITMP3); */
2234 /* M_CMPI(REG_ITMP3, 0); */
2237 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2240 codegen_addreference(cd, (basicblock *) iptr->target);
2242 M_CMPUI(s1, iptr->val.l & 0xffff);
2244 ICONST(REG_ITMP3, iptr->val.l >> 32);
2245 M_CMP(s2, REG_ITMP3);
2247 codegen_addreference(cd, (basicblock *) iptr->target);
2249 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2250 M_CMPU(s1, REG_ITMP3);
2253 codegen_addreference(cd, (basicblock *) iptr->target);
2256 case ICMD_IF_LNE: /* ..., value ==> ... */
2257 /* op1 = target JavaVM pc, val.l = constant */
2259 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2260 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2261 if (iptr->val.l == 0) {
2262 M_OR_TST(s1, s2, REG_ITMP3);
2263 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2264 M_XOR_IMM(s2, 0, REG_ITMP2);
2265 M_XOR_IMM(s1, iptr->val.l & 0xffff, REG_ITMP1);
2266 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2268 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2269 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2270 ICONST(REG_ITMP3, iptr->val.l >> 32);
2271 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2272 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2275 codegen_addreference(cd, (basicblock *) iptr->target);
2278 case ICMD_IF_LGT: /* ..., value ==> ... */
2279 /* op1 = target JavaVM pc, val.l = constant */
2281 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2282 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2283 /* if (iptr->val.l == 0) { */
2284 /* M_OR(s1, s2, REG_ITMP3); */
2285 /* M_CMPI(REG_ITMP3, 0); */
2288 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2291 codegen_addreference(cd, (basicblock *) iptr->target);
2293 M_CMPUI(s1, iptr->val.l & 0xffff);
2295 ICONST(REG_ITMP3, iptr->val.l >> 32);
2296 M_CMP(s2, REG_ITMP3);
2298 codegen_addreference(cd, (basicblock *) iptr->target);
2300 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2301 M_CMPU(s1, REG_ITMP3);
2304 codegen_addreference(cd, (basicblock *) iptr->target);
2307 case ICMD_IF_LGE: /* ..., value ==> ... */
2308 /* op1 = target JavaVM pc, val.l = constant */
2310 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2311 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2312 if (iptr->val.l == 0) {
2313 /* if high word is greater equal zero, the whole long is too */
2315 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2318 codegen_addreference(cd, (basicblock *) iptr->target);
2320 M_CMPUI(s1, iptr->val.l & 0xffff);
2322 ICONST(REG_ITMP3, iptr->val.l >> 32);
2323 M_CMP(s2, REG_ITMP3);
2325 codegen_addreference(cd, (basicblock *) iptr->target);
2327 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2328 M_CMPU(s1, REG_ITMP3);
2331 codegen_addreference(cd, (basicblock *) iptr->target);
2334 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2335 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2337 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2338 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2341 codegen_addreference(cd, (basicblock *) iptr->target);
2344 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2345 /* op1 = target JavaVM pc */
2347 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2348 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2350 /* load low-bits before the branch, so we know the distance */
2351 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2352 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2356 codegen_addreference(cd, (basicblock *) iptr->target);
2359 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2360 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2362 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2363 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2366 codegen_addreference(cd, (basicblock *) iptr->target);
2369 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2370 /* op1 = target JavaVM pc */
2372 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2373 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2376 codegen_addreference(cd, (basicblock *) iptr->target);
2377 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2378 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2381 codegen_addreference(cd, (basicblock *) iptr->target);
2384 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2385 /* op1 = target JavaVM pc */
2387 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2388 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2391 codegen_addreference(cd, (basicblock *) iptr->target);
2394 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2395 /* op1 = target JavaVM pc */
2397 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2398 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2401 codegen_addreference(cd, (basicblock *) iptr->target);
2402 /* load low-bits before the branch, so we know the distance */
2403 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2404 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2408 codegen_addreference(cd, (basicblock *) iptr->target);
2411 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2412 /* op1 = target JavaVM pc */
2414 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2415 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2418 codegen_addreference(cd, (basicblock *) iptr->target);
2421 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2422 /* op1 = target JavaVM pc */
2424 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2425 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2428 codegen_addreference(cd, (basicblock *) iptr->target);
2429 /* load low-bits before the branch, so we know the distance */
2430 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2431 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2435 codegen_addreference(cd, (basicblock *) iptr->target);
2438 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2439 /* op1 = target JavaVM pc */
2441 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2442 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2445 codegen_addreference(cd, (basicblock *) iptr->target);
2448 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2449 /* op1 = target JavaVM pc */
2451 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2452 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2455 codegen_addreference(cd, (basicblock *) iptr->target);
2456 /* load low-bits before the branch, so we know the distance */
2457 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2458 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2462 codegen_addreference(cd, (basicblock *) iptr->target);
2465 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2466 /* op1 = target JavaVM pc */
2468 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2469 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2472 codegen_addreference(cd, (basicblock *) iptr->target);
2475 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2476 /* op1 = target JavaVM pc */
2478 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2479 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2482 codegen_addreference(cd, (basicblock *) iptr->target);
2483 /* load low-bits before the branch, so we know the distance */
2484 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2485 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2489 codegen_addreference(cd, (basicblock *) iptr->target);
2492 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2493 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2495 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2496 M_LNGMOVE(s1, REG_RESULT);
2497 goto nowperformreturn;
2499 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2501 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2502 M_LNGMOVE(s1, REG_RESULT);
2504 #ifdef ENABLE_VERIFIER
2506 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2507 (unresolved_class *) iptr->val.a, 0);
2509 if (opt_showdisassemble)
2512 #endif /* ENABLE_VERIFIER */
2514 goto nowperformreturn;
2516 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2519 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2520 M_FLTMOVE(s1, REG_FRESULT);
2521 goto nowperformreturn;
2523 case ICMD_RETURN: /* ... ==> ... */
2531 /* call trace function */
2533 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2534 emit_verbosecall_exit(jd);
2537 #if defined(ENABLE_THREADS)
2538 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2539 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2540 M_ALD(REG_ITMP3, REG_PV, disp);
2541 M_ALD(REG_ITMP3, REG_ITMP3, 0); /* TOC */
2544 /* we need to save the proper return value */
2546 switch (iptr->opc) {
2551 M_LST(REG_RESULT , REG_SP, rd->memuse * 4 + 8);
2554 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
2557 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
2561 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2564 /* and now restore the proper return value */
2566 switch (iptr->opc) {
2571 M_LLD(REG_RESULT , REG_SP, rd->memuse * 4 + 8);
2574 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
2577 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 8);
2583 /* restore return address */
2585 if (!jd->isleafmethod) {
2586 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2587 may have a displacement overflow. */
2589 M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
2593 /* restore saved registers */
2595 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2596 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2598 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2599 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2602 /* deallocate stack */
2605 M_LDA(REG_SP, REG_SP, stackframesize * 8);
2613 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2618 tptr = (void **) iptr->target;
2620 s4ptr = iptr->val.a;
2621 l = s4ptr[1]; /* low */
2622 i = s4ptr[2]; /* high */
2624 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2626 M_INTMOVE(s1, REG_ITMP1);
2627 } else if (l <= 32768) {
2628 M_LDA(REG_ITMP1, s1, -l);
2630 ICONST(REG_ITMP2, l);
2631 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2637 M_CMPUI(REG_ITMP1, i - 1);
2639 codegen_addreference(cd, (basicblock *) tptr[0]);
2641 /* build jump table top down and use address of lowest entry */
2643 /* s4ptr += 3 + i; */
2647 dseg_addtarget(cd, (basicblock *) tptr[0]);
2652 /* length of dataseg after last dseg_addtarget is used by load */
2654 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2655 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2656 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2663 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2665 s4 i, l, val, *s4ptr;
2668 tptr = (void **) iptr->target;
2670 s4ptr = iptr->val.a;
2671 l = s4ptr[0]; /* default */
2672 i = s4ptr[1]; /* count */
2674 MCODECHECK((i<<2)+8);
2675 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2681 if ((val >= -32768) && (val <= 32767)) {
2684 a = dseg_adds4(cd, val);
2685 M_ILD(REG_ITMP2, REG_PV, a);
2686 M_CMP(s1, REG_ITMP2);
2689 codegen_addreference(cd, (basicblock *) tptr[0]);
2693 tptr = (void **) iptr->target;
2694 codegen_addreference(cd, (basicblock *) tptr[0]);
2701 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2702 /* op1 = arg count val.a = builtintable entry */
2708 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2709 /* op1 = arg count, val.a = method pointer */
2711 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2712 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2713 case ICMD_INVOKEINTERFACE:
2715 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2716 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
2720 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
2721 md = lm->parseddesc;
2725 s3 = md->paramcount;
2727 MCODECHECK((s3 << 1) + 64);
2729 /* copy arguments to registers or stack location */
2731 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2732 if (src->varkind == ARGVAR)
2734 if (IS_INT_LNG_TYPE(src->type)) {
2735 if (!md->params[s3].inmemory) {
2736 if (IS_2_WORD_TYPE(src->type)) {
2737 s1 = rd->argintregs[md->params[s3].regoff]; /* removed PACKREGS */
2738 d = emit_load_s1(jd, iptr, src, s1);
2741 s1 = rd->argintregs[md->params[s3].regoff];
2742 d = emit_load_s1(jd, iptr, src, s1);
2747 if (IS_2_WORD_TYPE(src->type)) {
2748 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
2749 M_LST(d, REG_SP, md->params[s3].regoff * 8); /* XXX */
2751 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
2752 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2757 if (!md->params[s3].inmemory) {
2758 s1 = rd->argfltregs[md->params[s3].regoff];
2759 d = emit_load_s1(jd, iptr, src, s1);
2763 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
2764 if (IS_2_WORD_TYPE(src->type))
2765 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2767 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2772 switch (iptr->opc) {
2774 disp = dseg_addaddress(cd, bte->fp);
2775 d = md->returntype.type;
2777 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function descriptor */
2778 M_ALD(REG_ITMP1, REG_PV, 0); /* function entry point address */
2779 M_ALD(REG_ITMP2, REG_PV, 8); /* TOC of callee */
2780 M_MOV(REG_TOC, REG_ITMP2); /* load TOC for callee */
2783 /* TODO: restore TOC */
2784 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2786 M_LDA(REG_PV, REG_ITMP1, -disp);
2788 /* if op1 == true, we need to check for an exception */
2790 if (iptr->op1 == true) {
2791 M_CMPI(REG_RESULT, 0);
2793 codegen_add_fillinstacktrace_ref(cd);
2797 case ICMD_INVOKESPECIAL:
2798 gen_nullptr_check(rd->argintregs[0]);
2799 M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */
2802 case ICMD_INVOKESTATIC:
2804 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2806 disp = dseg_addaddress(cd, NULL);
2808 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2811 if (opt_showdisassemble)
2814 d = md->returntype.type;
2817 disp = dseg_addaddress(cd, lm->stubroutine);
2818 d = md->returntype.type;
2821 M_ALD(REG_PV, REG_PV, disp);
2824 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2826 M_LDA(REG_PV, REG_ITMP1, -disp);
2829 case ICMD_INVOKEVIRTUAL:
2830 gen_nullptr_check(rd->argintregs[0]);
2833 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2835 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2837 if (opt_showdisassemble)
2841 d = md->returntype.type;
2844 s1 = OFFSET(vftbl_t, table[0]) +
2845 sizeof(methodptr) * lm->vftblindex;
2846 d = md->returntype.type;
2849 M_ALD(REG_METHODPTR, rd->argintregs[0],
2850 OFFSET(java_objectheader, vftbl));
2851 M_ALD(REG_PV, REG_METHODPTR, s1);
2854 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2856 M_LDA(REG_PV, REG_ITMP1, -disp);
2859 case ICMD_INVOKEINTERFACE:
2860 gen_nullptr_check(rd->argintregs[0]);
2863 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2865 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2867 if (opt_showdisassemble)
2872 d = md->returntype.type;
2875 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2876 sizeof(methodptr*) * lm->class->index;
2878 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2880 d = md->returntype.type;
2883 M_ALD(REG_METHODPTR, rd->argintregs[0],
2884 OFFSET(java_objectheader, vftbl));
2885 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2886 M_ALD(REG_PV, REG_METHODPTR, s2);
2889 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2891 M_LDA(REG_PV, REG_ITMP1, -disp);
2895 /* d contains return type */
2897 if (d != TYPE_VOID) {
2898 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2899 if (IS_2_WORD_TYPE(iptr->dst->type)) {
2900 /*s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst,
2901 PACK_REGS(REG_RESULT2, REG_RESULT)); FIXME*/
2902 /*M_LNGMOVE(PACK_REGS(REG_RESULT2, REG_RESULT), s1); FIXME*/
2904 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
2905 M_INTMOVE(REG_RESULT, s1);
2908 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
2909 M_FLTMOVE(REG_FRESULT, s1);
2911 emit_store(jd, iptr, iptr->dst, s1);
2916 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2917 /* op1: 0 == array, 1 == class */
2918 /* val.a: (classinfo*) superclass */
2920 /* superclass is an interface:
2922 * OK if ((sub == NULL) ||
2923 * (sub->vftbl->interfacetablelength > super->index) &&
2924 * (sub->vftbl->interfacetable[-super->index] != NULL));
2926 * superclass is a class:
2928 * OK if ((sub == NULL) || (0
2929 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2930 * super->vftbl->diffvall));
2933 if (iptr->op1 == 1) {
2934 /* object type cast-check */
2937 vftbl_t *supervftbl;
2940 super = (classinfo *) iptr->val.a;
2947 superindex = super->index;
2948 supervftbl = super->vftbl;
2951 #if defined(ENABLE_THREADS)
2952 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2954 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2956 /* calculate interface checkcast code size */
2960 s2 += (opt_showdisassemble ? 1 : 0);
2962 /* calculate class checkcast code size */
2964 s3 = 8 + (s1 == REG_ITMP1);
2966 s3 += (opt_showdisassemble ? 1 : 0);
2968 /* if class is not resolved, check which code to call */
2972 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
2974 disp = dseg_adds4(cd, 0); /* super->flags */
2976 codegen_addpatchref(cd,
2977 PATCHER_checkcast_instanceof_flags,
2978 (constant_classref *) iptr->target,
2981 if (opt_showdisassemble)
2984 M_ILD(REG_ITMP2, REG_PV, disp);
2985 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2989 /* interface checkcast code */
2991 if (!super || (super->flags & ACC_INTERFACE)) {
2997 codegen_addpatchref(cd,
2998 PATCHER_checkcast_instanceof_interface,
2999 (constant_classref *) iptr->target,
3002 if (opt_showdisassemble)
3006 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3007 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3008 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3010 codegen_add_classcastexception_ref(cd, s1); /*XXX s1?? */
3011 M_ALD(REG_ITMP3, REG_ITMP2,
3012 OFFSET(vftbl_t, interfacetable[0]) -
3013 superindex * sizeof(methodptr*));
3016 codegen_add_classcastexception_ref(cd, s1); /*XXX s1??*/
3022 /* class checkcast code */
3024 if (!super || !(super->flags & ACC_INTERFACE)) {
3025 disp = dseg_addaddress(cd, supervftbl);
3032 codegen_addpatchref(cd, PATCHER_checkcast_class,
3033 (constant_classref *) iptr->target,
3036 if (opt_showdisassemble)
3040 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3041 #if defined(ENABLE_THREADS)
3042 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3044 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3045 M_ALD(REG_ITMP2, REG_PV, disp);
3046 if (s1 != REG_ITMP1) {
3047 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
3048 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3049 #if defined(ENABLE_THREADS)
3050 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3052 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
3054 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3055 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3056 M_ALD(REG_ITMP2, REG_PV, disp);
3057 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3058 #if defined(ENABLE_THREADS)
3059 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3062 M_CMPU(REG_ITMP3, REG_ITMP2);
3064 codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */
3066 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3069 /* array type cast-check */
3071 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3072 M_INTMOVE(s1, rd->argintregs[0]);
3074 disp = dseg_addaddress(cd, iptr->val.a);
3076 if (iptr->val.a == NULL) {
3077 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3078 (constant_classref *) iptr->target,
3081 if (opt_showdisassemble)
3085 M_ALD(rd->argintregs[1], REG_PV, disp);
3086 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3087 M_ALD(REG_ITMP2, REG_PV, disp);
3092 codegen_add_classcastexception_ref(cd, s1); /* XXX s1? */
3094 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3095 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3098 emit_store(jd, iptr, iptr->dst, d);
3101 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3102 /* val.a: (classinfo*) superclass */
3104 /* superclass is an interface:
3106 * return (sub != NULL) &&
3107 * (sub->vftbl->interfacetablelength > super->index) &&
3108 * (sub->vftbl->interfacetable[-super->index] != NULL);
3110 * superclass is a class:
3112 * return ((sub != NULL) && (0
3113 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3114 * super->vftbl->diffvall));
3119 vftbl_t *supervftbl;
3122 super = (classinfo *) iptr->val.a;
3129 superindex = super->index;
3130 supervftbl = super->vftbl;
3133 #if defined(ENABLE_THREADS)
3134 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3136 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3137 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3139 M_MOV(s1, REG_ITMP1);
3143 /* calculate interface instanceof code size */
3147 s2 += (opt_showdisassemble ? 1 : 0);
3149 /* calculate class instanceof code size */
3153 s3 += (opt_showdisassemble ? 1 : 0);
3157 /* if class is not resolved, check which code to call */
3161 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3163 disp = dseg_adds4(cd, 0); /* super->flags */
3165 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3166 (constant_classref *) iptr->target, disp);
3168 if (opt_showdisassemble)
3171 M_ILD(REG_ITMP3, REG_PV, disp);
3172 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3176 /* interface instanceof code */
3178 if (!super || (super->flags & ACC_INTERFACE)) {
3184 codegen_addpatchref(cd,
3185 PATCHER_checkcast_instanceof_interface,
3186 (constant_classref *) iptr->target, 0);
3188 if (opt_showdisassemble)
3192 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3193 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3194 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3196 M_ALD(REG_ITMP1, REG_ITMP1,
3197 OFFSET(vftbl_t, interfacetable[0]) -
3198 superindex * sizeof(methodptr*));
3201 M_IADD_IMM(REG_ZERO, 1, d);
3207 /* class instanceof code */
3209 if (!super || !(super->flags & ACC_INTERFACE)) {
3210 disp = dseg_addaddress(cd, supervftbl);
3217 codegen_addpatchref(cd, PATCHER_instanceof_class,
3218 (constant_classref *) iptr->target,
3221 if (opt_showdisassemble) {
3226 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3227 M_ALD(REG_ITMP2, REG_PV, disp);
3228 #if defined(ENABLE_THREADS)
3229 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3231 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3232 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3233 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3234 #if defined(ENABLE_THREADS)
3235 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3237 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3238 M_CMPU(REG_ITMP1, REG_ITMP2);
3241 M_IADD_IMM(REG_ZERO, 1, d);
3243 emit_store(jd, iptr, iptr->dst, d);
3247 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3248 /* op1 = dimension, val.a = class */
3250 /* check for negative sizes and copy sizes to stack if necessary */
3252 MCODECHECK((iptr->op1 << 1) + 64);
3254 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3255 /* copy SAVEDVAR sizes to stack */
3257 if (src->varkind != ARGVAR) {
3258 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3259 #if defined(__DARWIN__)
3260 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
3262 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
3267 /* a0 = dimension count */
3269 ICONST(rd->argintregs[0], iptr->op1);
3271 /* is patcher function set? */
3273 if (iptr->val.a == NULL) {
3274 disp = dseg_addaddress(cd, NULL);
3276 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3277 (constant_classref *) iptr->target, disp);
3279 if (opt_showdisassemble)
3283 disp = dseg_addaddress(cd, iptr->val.a);
3286 /* a1 = arraydescriptor */
3288 M_ALD(rd->argintregs[1], REG_PV, disp);
3290 /* a2 = pointer to dimensions = stack pointer */
3292 #if defined(__DARWIN__)
3293 M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 4);
3295 M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 4);
3298 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3299 M_ALD(REG_ITMP3, REG_PV, disp);
3303 /* check for exception before result assignment */
3305 M_CMPI(REG_RESULT, 0);
3307 codegen_add_fillinstacktrace_ref(cd);
3309 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3310 M_INTMOVE(REG_RESULT, d);
3311 emit_store(jd, iptr, iptr->dst, d);
3316 new_internalerror("Unknown ICMD %d during code generation",
3321 } /* for instruction */
3323 /* copy values to interface registers */
3325 src = bptr->outstack;
3326 len = bptr->outdepth;
3327 MCODECHECK(64 + len);
3328 #if defined(ENABLE_LSRA)
3333 if ((src->varkind != STACKVAR)) {
3335 if (IS_FLT_DBL_TYPE(s2)) {
3336 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3337 if (!(rd->interfaces[len][s2].flags & INMEMORY))
3338 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
3340 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3343 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3344 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3345 if (IS_2_WORD_TYPE(s2))
3346 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
3348 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3351 if (IS_2_WORD_TYPE(s2))
3352 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3354 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3360 } /* if (bptr -> flags >= BBREACHED) */
3361 } /* for basic block */
3363 dseg_createlinenumbertable(cd);
3366 /* generate exception and patcher stubs */
3375 savedmcodeptr = NULL;
3377 /* generate exception stubs */
3379 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3380 gen_resolvebranch(cd->mcodebase + eref->branchpos,
3381 eref->branchpos, cd->mcodeptr - cd->mcodebase);
3385 /* Check if the exception is an
3386 ArrayIndexOutOfBoundsException. If so, move index register
3389 if (eref->reg != -1)
3390 M_MOV(eref->reg, REG_ITMP1);
3392 /* calcuate exception address */
3394 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3396 /* move function to call into REG_ITMP3 */
3398 disp = dseg_addaddress(cd, eref->function);
3399 M_ALD(REG_ITMP3, REG_PV, disp);
3401 if (savedmcodeptr != NULL) {
3402 disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
3406 savedmcodeptr = cd->mcodeptr;
3408 if (jd->isleafmethod) {
3410 M_AST(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
3413 M_MOV(REG_PV, rd->argintregs[0]);
3414 M_MOV(REG_SP, rd->argintregs[1]);
3416 if (jd->isleafmethod)
3417 M_MOV(REG_ZERO, rd->argintregs[2]);
3419 M_ALD(rd->argintregs[2],
3420 REG_SP, stackframesize * 8 + LA_LR_OFFSET);
3422 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3423 M_MOV(REG_ITMP1, rd->argintregs[4]);
3425 M_STDU(REG_SP, REG_SP, -(LA_SIZE + 6 * 8));
3426 M_AST(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8);
3430 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3432 M_ALD(REG_ITMP2_XPC, REG_SP, LA_SIZE + 5 * 8);
3433 M_LADD_IMM(REG_SP, LA_SIZE + 6 * 8, REG_SP);
3435 if (jd->isleafmethod) {
3436 /* XXX FIXME: REG_ZERO can cause problems here! */
3437 assert(stackframesize * 8 <= 32767);
3439 M_ALD(REG_ZERO, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
3443 disp = dseg_addaddress(cd, asm_handle_exception);
3444 M_ALD(REG_ITMP3, REG_PV, disp);
3451 /* generate code patching stub call code */
3453 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3454 /* check code segment size */
3458 /* Get machine code which is patched back in later. The
3459 call is 1 instruction word long. */
3461 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
3463 mcode = *((u4 *) tmpmcodeptr);
3465 /* Patch in the call to call the following code (done at
3468 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3469 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3471 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3474 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3476 /* create stack frame - keep stack 16-byte aligned */
3478 M_AADD_IMM(REG_SP, -8 * 8, REG_SP);
3480 /* calculate return address and move it onto the stack */
3482 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3483 M_AST_INTERN(REG_ITMP3, REG_SP, 5 * 8);
3485 /* move pointer to java_objectheader onto stack */
3487 #if defined(ENABLE_THREADS)
3488 /* order reversed because of data segment layout */
3490 (void) dseg_addaddress(cd, NULL); /* flcword */
3491 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
3492 disp = dseg_addaddress(cd, NULL); /* vftbl */
3494 M_LDA(REG_ITMP3, REG_PV, disp);
3495 M_AST_INTERN(REG_ITMP3, REG_SP, 4 * 8);
3500 /* move machine code onto stack */
3502 disp = dseg_adds4(cd, mcode);
3503 M_ILD(REG_ITMP3, REG_PV, disp);
3504 M_IST_INTERN(REG_ITMP3, REG_SP, 3 * 8);
3506 /* move class/method/field reference onto stack */
3508 disp = dseg_addaddress(cd, pref->ref);
3509 M_ALD(REG_ITMP3, REG_PV, disp);
3510 M_AST_INTERN(REG_ITMP3, REG_SP, 2 * 8);
3512 /* move data segment displacement onto stack */
3514 disp = dseg_addaddress(cd, pref->disp);
3515 M_LLD(REG_ITMP3, REG_PV, disp);
3516 M_IST_INTERN(REG_ITMP3, REG_SP, 1 * 8);
3518 /* move patcher function pointer onto stack */
3520 disp = dseg_addaddress(cd, pref->patcher);
3521 M_ALD(REG_ITMP3, REG_PV, disp);
3522 M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 8);
3524 disp = dseg_addaddress(cd, asm_patcher_wrapper);
3525 M_ALD(REG_ITMP3, REG_PV, disp);
3530 /* generate replacement-out stubs */
3535 replacementpoint = jd->code->rplpoints;
3537 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3538 /* check code segment size */
3542 /* note start of stub code */
3544 replacementpoint->outcode = (u1 *) (cd->mcodeptr - cd->mcodebase);
3546 /* make machine code for patching */
3548 tmpmcodeptr = cd->mcodeptr;
3549 cd->mcodeptr = (u1 *) &(replacementpoint->mcode) + 1 /* big-endian */;
3551 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3554 cd->mcodeptr = tmpmcodeptr;
3556 /* create stack frame - keep 16-byte aligned */
3558 M_AADD_IMM(REG_SP, -4 * 4, REG_SP);
3560 /* push address of `rplpoint` struct */
3562 disp = dseg_addaddress(cd, replacementpoint);
3563 M_ALD(REG_ITMP3, REG_PV, disp);
3564 M_AST_INTERN(REG_ITMP3, REG_SP, 0 * 4);
3566 /* jump to replacement function */
3568 disp = dseg_addaddress(cd, asm_replacement_out);
3569 M_ALD(REG_ITMP3, REG_PV, disp);
3578 /* everything's ok */
3584 /* createcompilerstub **********************************************************
3586 Creates a stub routine which calls the compiler.
3588 *******************************************************************************/
3590 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3591 #define COMPILERSTUB_CODESIZE 4 * 4
3593 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3596 u1 *createcompilerstub(methodinfo *m)
3598 u1 *s; /* memory to hold the stub */
3604 s = CNEW(u1, COMPILERSTUB_SIZE);
3606 /* set data pointer and code pointer */
3609 s = s + COMPILERSTUB_DATASIZE;
3611 /* mark start of dump memory area */
3613 dumpsize = dump_size();
3615 cd = DNEW(codegendata);
3618 /* Store the codeinfo pointer in the same place as in the
3619 methodheader for compiled methods. */
3621 code = code_codeinfo_new(m);
3623 d[0] = (ptrint) asm_call_jit_compiler;
3625 d[2] = (ptrint) code;
3627 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
3628 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
3632 md_cacheflush((u1 *) d, COMPILERSTUB_SIZE);
3634 #if defined(ENABLE_STATISTICS)
3636 count_cstub_len += COMPILERSTUB_SIZE;
3639 /* release dump area */
3641 dump_release(dumpsize);
3647 /* createnativestub ************************************************************
3649 Creates a stub routine which calls a native method.
3651 *******************************************************************************/
3653 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3659 s4 stackframesize; /* size of stackframe if needed */
3662 s4 i, j; /* count variables */
3667 /* get required compiler data */
3674 /* set some variables */
3677 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3679 /* calculate stackframe size */
3682 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3683 sizeof(localref_table) / SIZEOF_VOID_P +
3684 4 + /* 4 stackframeinfo arguments (darwin)*/
3688 stackframesize = (stackframesize + 3) & ~3; /* keep stack 16-byte aligned */
3690 /* create method header */
3692 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3693 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
3694 (void) dseg_adds4(cd, 0); /* IsSync */
3695 (void) dseg_adds4(cd, 0); /* IsLeaf */
3696 (void) dseg_adds4(cd, 0); /* IntSave */
3697 (void) dseg_adds4(cd, 0); /* FltSave */
3698 (void) dseg_addlinenumbertablesize(cd);
3699 (void) dseg_adds4(cd, 0); /* ExTableSize */
3704 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
3705 M_STDU(REG_SP, REG_SP, -(stackframesize * 8));
3707 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3708 emit_verbosecall_enter(jd);
3711 /* get function address (this must happen before the stackframeinfo) */
3713 funcdisp = dseg_addaddress(cd, f);
3715 #if !defined(WITH_STATIC_CLASSPATH)
3717 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3719 if (opt_showdisassemble)
3724 /* save integer and float argument registers */
3728 for (i = 0; i < md->paramcount; i++) {
3729 t = md->paramtypes[i].type;
3731 if (IS_INT_LNG_TYPE(t)) {
3732 if (!md->params[i].inmemory) {
3733 s1 = md->params[i].regoff;
3734 M_LST(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
3740 for (i = 0; i < md->paramcount; i++) {
3741 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3742 if (!md->params[i].inmemory) {
3743 s1 = md->params[i].regoff;
3744 M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
3750 /* create native stack info */
3752 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]);
3753 M_MOV(REG_PV, rd->argintregs[1]);
3754 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
3755 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 + LA_LR_OFFSET);
3756 disp = dseg_addaddress(cd, codegen_start_native_call);
3757 M_ALD(REG_ITMP1, REG_PV, disp);
3758 M_ALD(REG_ITMP1, REG_ITMP1, 0); /* FIXME what about TOC? */
3766 /* restore integer and float argument registers */
3770 for (i = 0; i < md->paramcount; i++) {
3771 t = md->paramtypes[i].type;
3773 if (IS_INT_LNG_TYPE(t)) {
3774 if (!md->params[i].inmemory) {
3775 s1 = md->params[i].regoff;
3776 M_LLD(rd->argintregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
3782 for (i = 0; i < md->paramcount; i++) {
3783 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3784 if (!md->params[i].inmemory) {
3785 s1 = md->params[i].regoff;
3786 M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + PA_SIZE + 4 * 8 + j * 8);
3792 /* copy or spill arguments to new locations */
3794 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3795 t = md->paramtypes[i].type;
3797 if (IS_INT_LNG_TYPE(t)) {
3798 if (!md->params[i].inmemory) {
3799 s1 = rd->argintregs[md->params[i].regoff];
3801 if (!nmd->params[j].inmemory) {
3802 s2 = rd->argintregs[nmd->params[j].regoff];
3805 s2 = nmd->params[j].regoff;
3806 M_LST(s1, REG_SP, s2 * 8);
3810 s1 = md->params[i].regoff + stackframesize;
3811 s2 = nmd->params[j].regoff;
3813 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3814 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3818 /* We only copy spilled float arguments, as the float
3819 argument registers keep unchanged. */
3821 if (md->params[i].inmemory) {
3822 s1 = md->params[i].regoff + stackframesize;
3823 s2 = nmd->params[j].regoff;
3825 if (IS_2_WORD_TYPE(t)) {
3826 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3827 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3830 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3831 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3837 /* put class into second argument register */
3839 if (m->flags & ACC_STATIC) {
3840 disp = dseg_addaddress(cd, m->class);
3841 M_ALD(rd->argintregs[1], REG_PV, disp);
3844 /* put env into first argument register */
3846 disp = dseg_addaddress(cd, _Jv_env);
3847 M_ALD(rd->argintregs[0], REG_PV, disp);
3849 /* generate the actual native call */
3851 M_ALD(REG_ITMP3, REG_PV, funcdisp);
3852 M_ALD(REG_ITMP3, REG_ITMP3, 0); /* XXX what about TOC ? */
3860 /* save return value */
3862 if (md->returntype.type != TYPE_VOID) {
3863 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3864 M_LST(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
3867 if (IS_2_WORD_TYPE(md->returntype.type))
3868 M_DST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
3870 M_FST(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8); /* FIXME, needed ?*/
3874 /* print call trace */
3876 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3877 emit_verbosecall_exit(jd);
3880 /* remove native stackframe info */
3886 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[0]);
3887 disp = dseg_addaddress(cd, codegen_finish_native_call);
3888 M_ALD(REG_ITMP1, REG_PV, disp);
3889 M_ALD(REG_ITMP1, REG_ITMP1, 0); /* XXX what about TOC? */
3892 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3894 /* restore return value */
3896 if (md->returntype.type != TYPE_VOID) {
3897 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3898 M_LLD(REG_RESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
3901 if (IS_2_WORD_TYPE(md->returntype.type))
3902 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
3904 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + PA_SIZE + 1 * 8);
3908 M_ALD(REG_ITMP2_XPC, REG_SP, stackframesize * 8 + LA_LR_OFFSET);
3909 M_MTLR(REG_ITMP2_XPC);
3910 M_LDA(REG_SP, REG_SP, stackframesize * 8); /* remove stackframe */
3912 /* check for exception */
3914 M_TST(REG_ITMP1_XPTR);
3915 M_BNE(1); /* if no exception then return */
3919 /* handle exception */
3921 M_LADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3923 disp = dseg_addaddress(cd, asm_handle_nat_exception);
3924 M_ALD(REG_ITMP3, REG_PV, disp);
3928 /* generate patcher stub call code */
3936 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3937 /* Get machine code which is patched back in later. The
3938 call is 1 instruction word long. */
3940 tmpmcodeptr = cd->mcodebase + pref->branchpos;
3942 mcode = *((u4 *) tmpmcodeptr);
3944 /* Patch in the call to call the following code (done at
3947 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3948 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3950 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3953 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3955 /* create stack frame - keep stack 16-byte aligned */
3957 M_AADD_IMM(REG_SP, -8 * 8, REG_SP);
3959 /* move return address onto stack */
3962 M_AST(REG_ZERO, REG_SP, 5 * 8);
3964 /* move pointer to java_objectheader onto stack */
3966 #if defined(ENABLE_THREADS)
3967 /* order reversed because of data segment layout */
3969 (void) dseg_addaddress(cd, NULL); /* flcword */
3970 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
3971 disp = dseg_addaddress(cd, NULL); /* vftbl */
3973 M_LDA(REG_ITMP3, REG_PV, disp);
3974 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3979 /* move machine code onto stack */
3981 disp = dseg_adds4(cd, mcode);
3982 M_ILD(REG_ITMP3, REG_PV, disp);
3983 M_IST(REG_ITMP3, REG_SP, 3 * 8);
3985 /* move class/method/field reference onto stack */
3987 disp = dseg_addaddress(cd, pref->ref);
3988 M_ALD(REG_ITMP3, REG_PV, disp);
3989 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3991 /* move data segment displacement onto stack */
3993 disp = dseg_adds4(cd, pref->disp);
3994 M_ILD(REG_ITMP3, REG_PV, disp);
3995 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3997 /* move patcher function pointer onto stack */
3999 disp = dseg_addaddress(cd, pref->patcher);
4000 M_ALD(REG_ITMP3, REG_PV, disp);
4001 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4003 disp = dseg_addaddress(cd, asm_patcher_wrapper);
4004 M_ALD(REG_ITMP3, REG_PV, disp);
4012 return code->entrypoint;
4019 * These are local overrides for various environment variables in Emacs.
4020 * Please do not remove this and leave it at the end of the file, where
4021 * Emacs will automagically detect them.
4022 * ---------------------------------------------------------------------
4025 * indent-tabs-mode: t
4029 * vim:noexpandtab:sw=4:ts=4: