1 /* src/vm/jit/powerpc/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 5354 2006-09-05 23:08:01Z twisti $
49 #include "vm/jit/powerpc/arch.h"
50 #include "vm/jit/powerpc/codegen.h"
52 #include "mm/memory.h"
53 #include "native/native.h"
55 #if defined(ENABLE_THREADS)
56 # include "threads/native/lock.h"
59 #include "vm/builtin.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
66 #include "vm/jit/abi-asm.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/methodheader.h"
73 #include "vm/jit/parse.h"
74 #include "vm/jit/patcher.h"
75 #include "vm/jit/reg.h"
76 #include "vm/jit/replace.h"
78 #if defined(ENABLE_LSRA)
79 # include "vm/jit/allocator/lsra.h"
83 /* codegen *********************************************************************
85 Generates machine code.
87 *******************************************************************************/
89 bool codegen(jitdata *jd)
95 s4 len, s1, s2, s3, d, disp;
104 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
105 builtintable_entry *bte;
107 rplpoint *replacementpoint;
109 /* get required compiler data */
116 /* prevent compiler warnings */
128 /* space to save used callee saved registers */
130 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
131 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
133 cd->stackframesize = rd->memuse + savedregs_num;
135 #if defined(ENABLE_THREADS)
136 /* Space to save argument of monitor_enter and Return Values to
137 survive monitor_exit. The stack position for the argument can
138 not be shared with place to save the return register on PPC,
139 since both values reside in R3. */
141 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
142 /* reserve 2 slots for long/double return values for monitorexit */
144 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
145 cd->stackframesize += 3;
147 cd->stackframesize += 2;
152 /* create method header */
154 /* align stack to 16-bytes */
156 if (!jd->isleafmethod || JITDATA_HAS_FLAG_VERBOSECALL(jd))
157 cd->stackframesize = (cd->stackframesize + 3) & ~3;
159 else if (jd->isleafmethod && (cd->stackframesize == LA_SIZE_IN_POINTERS))
160 cd->stackframesize = 0;
162 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
163 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
165 #if defined(ENABLE_THREADS)
166 /* IsSync contains the offset relative to the stack pointer for the
167 argument of monitor_exit used in the exception handler. Since the
168 offset could be zero and give a wrong meaning of the flag it is
172 if (checksync && (m->flags & ACC_SYNCHRONIZED))
173 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync */
176 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
178 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
179 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
180 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
182 dseg_addlinenumbertablesize(cd);
184 (void) dseg_add_unique_s4(cd, cd->exceptiontablelength); /* ExTableSize */
186 /* create exception table */
188 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
189 dseg_add_target(cd, ex->start);
190 dseg_add_target(cd, ex->end);
191 dseg_add_target(cd, ex->handler);
192 (void) dseg_add_unique_address(cd, ex->catchtype.cls);
195 /* generate method profiling code */
197 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
198 /* count frequency */
200 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
201 M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
202 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
203 M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
205 /* PROFILE_CYCLE_START; */
208 /* create stack frame (if necessary) */
210 if (!jd->isleafmethod) {
212 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
215 if (cd->stackframesize)
216 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
218 /* save return address and used callee saved registers */
220 p = cd->stackframesize;
221 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
222 p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
224 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
225 p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
228 /* take arguments out of register or stack frame */
232 for (p = 0, l = 0; p < md->paramcount; p++) {
233 t = md->paramtypes[p].type;
234 var = &(rd->locals[l][t]);
236 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
240 s1 = md->params[p].regoff;
241 if (IS_INT_LNG_TYPE(t)) { /* integer args */
242 if (IS_2_WORD_TYPE(t))
243 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
244 rd->argintregs[GET_HIGH_REG(s1)]);
246 s2 = rd->argintregs[s1];
247 if (!md->params[p].inmemory) { /* register arguments */
248 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
249 if (IS_2_WORD_TYPE(t))
250 M_LNGMOVE(s2, var->regoff);
252 M_INTMOVE(s2, var->regoff);
254 } else { /* reg arg -> spilled */
255 if (IS_2_WORD_TYPE(t))
256 M_LST(s2, REG_SP, var->regoff * 4);
258 M_IST(s2, REG_SP, var->regoff * 4);
261 } else { /* stack arguments */
262 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
263 if (IS_2_WORD_TYPE(t))
264 M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
266 M_ILD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
268 } else { /* stack arg -> spilled */
270 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
271 M_IST(REG_ITMP1, REG_SP, var->regoff * 4);
272 if (IS_2_WORD_TYPE(t)) {
273 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
274 M_IST(REG_ITMP1, REG_SP, var->regoff * 4 + 4);
277 /* Reuse Memory Position on Caller Stack */
278 var->regoff = cd->stackframesize + s1;
283 } else { /* floating args */
284 if (!md->params[p].inmemory) { /* register arguments */
285 s2 = rd->argfltregs[s1];
286 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
287 M_FLTMOVE(s2, var->regoff);
289 } else { /* reg arg -> spilled */
290 if (IS_2_WORD_TYPE(t))
291 M_DST(s2, REG_SP, var->regoff * 4);
293 M_FST(s2, REG_SP, var->regoff * 4);
296 } else { /* stack arguments */
297 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
298 if (IS_2_WORD_TYPE(t))
299 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
302 M_FLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
304 } else { /* stack-arg -> spilled */
306 if (IS_2_WORD_TYPE(t)) {
307 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
308 M_DST(REG_FTMP1, REG_SP, var->regoff * 4);
309 var->regoff = cd->stackframesize + s1;
312 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
313 M_FST(REG_FTMP1, REG_SP, var->regoff * 4);
316 /* Reuse Memory Position on Caller Stack */
317 var->regoff = cd->stackframesize + s1;
324 #if defined(ENABLE_THREADS)
325 /* call monitorenter function */
327 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
328 /* stack offset for monitor argument */
332 # if !defined(NDEBUG)
333 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
334 M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
336 for (p = 0; p < INT_ARG_CNT; p++)
337 M_IST(rd->argintregs[p], REG_SP, LA_SIZE + p * 8);
339 for (p = 0; p < FLT_ARG_CNT; p++)
340 M_DST(rd->argfltregs[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
342 /* ATTENTION: We multiply here with 2, because we use * 8
343 above for simplicity and below * 4! */
345 s1 += (LA_SIZE_IN_POINTERS + ARG_CNT) * 2;
349 p = dseg_add_functionptr(cd, LOCK_monitor_enter);
350 M_ALD(REG_ITMP3, REG_PV, p);
353 /* get or test the lock object */
355 if (m->flags & ACC_STATIC) {
356 p = dseg_add_address(cd, &m->class->object.header);
357 M_ALD(rd->argintregs[0], REG_PV, p);
360 M_TST(rd->argintregs[0]);
362 codegen_add_nullpointerexception_ref(cd);
365 M_AST(rd->argintregs[0], REG_SP, s1 * 4);
368 # if !defined(NDEBUG)
369 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
370 for (p = 0; p < INT_ARG_CNT; p++)
371 M_ILD(rd->argintregs[p], REG_SP, LA_SIZE + p * 8);
373 for (p = 0; p < FLT_ARG_CNT; p++)
374 M_DLD(rd->argfltregs[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
376 M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
380 #endif /* defined(ENABLE_THREADS) */
382 /* call trace function */
384 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
385 emit_verbosecall_enter(jd);
388 /* end of header generation */
390 replacementpoint = code->rplpoints;
392 /* walk through all basic blocks */
394 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
396 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
398 if (bptr->flags >= BBREACHED) {
400 /* branch resolving */
404 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
405 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
411 /* handle replacement points */
413 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
414 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
419 /* generate basicblock profiling code */
421 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
422 /* count frequency */
424 disp = dseg_add_address(cd, code->bbfrequency);
425 M_ALD(REG_ITMP2, REG_PV, disp);
426 M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
427 M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
428 M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
430 /* if this is an exception handler, start profiling again */
432 /* if (bptr->type == BBTYPE_EXH) */
433 /* PROFILE_CYCLE_START; */
436 /* copy interface registers to their destination */
442 #if defined(ENABLE_LSRA)
444 while (src != NULL) {
446 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
447 /* d = reg_of_var(m, src, REG_ITMP1); */
448 if (!(src->flags & INMEMORY))
452 M_INTMOVE(REG_ITMP1, d);
453 emit_store(jd, NULL, src, d);
459 while (src != NULL) {
461 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
462 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
463 M_INTMOVE(REG_ITMP1, d);
464 emit_store(jd, NULL, src, d);
467 if (src->type == TYPE_LNG)
468 d = codegen_reg_of_var(rd, 0, src, REG_ITMP12_PACKED);
470 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
471 if ((src->varkind != STACKVAR)) {
473 if (IS_FLT_DBL_TYPE(s2)) {
474 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
475 s1 = rd->interfaces[len][s2].regoff;
479 if (IS_2_WORD_TYPE(s2)) {
481 rd->interfaces[len][s2].regoff * 4);
485 rd->interfaces[len][s2].regoff * 4);
488 emit_store(jd, NULL, src, d);
491 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
492 s1 = rd->interfaces[len][s2].regoff;
493 if (IS_2_WORD_TYPE(s2))
499 if (IS_2_WORD_TYPE(s2))
501 rd->interfaces[len][s2].regoff * 4);
504 rd->interfaces[len][s2].regoff * 4);
506 emit_store(jd, NULL, src, d);
513 #if defined(ENABLE_LSRA)
516 /* walk through all instructions */
522 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
523 if (iptr->line != currentline) {
524 dseg_addlinenumber(cd, iptr->line);
525 currentline = iptr->line;
528 MCODECHECK(64); /* an instruction usually needs < 64 words */
531 case ICMD_NOP: /* ... ==> ... */
532 case ICMD_INLINE_START:
533 case ICMD_INLINE_END:
536 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
541 codegen_add_nullpointerexception_ref(cd);
544 /* constant operations ************************************************/
546 case ICMD_ICONST: /* ... ==> ..., constant */
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
549 ICONST(d, iptr->sx.val.i);
550 emit_store_dst(jd, iptr, d);
553 case ICMD_LCONST: /* ... ==> ..., constant */
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
556 LCONST(d, iptr->sx.val.l);
557 emit_store_dst(jd, iptr, d);
560 case ICMD_FCONST: /* ... ==> ..., constant */
562 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
563 a = dseg_add_float(cd, iptr->sx.val.f);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_DCONST: /* ... ==> ..., constant */
570 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
571 a = dseg_add_double(cd, iptr->sx.val.d);
573 emit_store_dst(jd, iptr, d);
576 case ICMD_ACONST: /* ... ==> ..., constant */
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
580 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
581 constant_classref *cr = iptr->sx.val.c.ref;;
583 disp = dseg_add_unique_address(cd, cr);
585 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
588 if (opt_showdisassemble)
592 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
594 M_ALD(d, REG_PV, disp);
595 emit_store_dst(jd, iptr, d);
599 /* load/store operations **********************************************/
601 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
602 case ICMD_ALOAD: /* op1 = local variable */
604 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
606 if ((iptr->dst.var->varkind == LOCALVAR) &&
607 (iptr->dst.var->varnum == iptr->s1.localindex))
609 if (var->flags & INMEMORY)
610 M_ILD(d, REG_SP, var->regoff * 4);
612 M_INTMOVE(var->regoff, d);
613 emit_store_dst(jd, iptr, d);
616 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
617 /* s1.localindex = local variable */
619 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
620 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
621 if ((iptr->dst.var->varkind == LOCALVAR) &&
622 (iptr->dst.var->varnum == iptr->s1.localindex))
624 if (var->flags & INMEMORY)
625 M_LLD(d, REG_SP, var->regoff * 4);
627 M_LNGMOVE(var->regoff, d);
628 emit_store_dst(jd, iptr, d);
631 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
632 /* s1.localindex = local variable */
634 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
635 if ((iptr->dst.var->varkind == LOCALVAR) &&
636 (iptr->dst.var->varnum == iptr->s1.localindex))
638 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
639 if (var->flags & INMEMORY)
640 M_FLD(d, REG_SP, var->regoff * 4);
642 M_FLTMOVE(var->regoff, d);
643 emit_store_dst(jd, iptr, d);
646 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
647 /* s1.localindex = local variable */
649 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
650 if ((iptr->dst.var->varkind == LOCALVAR) &&
651 (iptr->dst.var->varnum == iptr->s1.localindex))
653 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
654 if (var->flags & INMEMORY)
655 M_DLD(d, REG_SP, var->regoff * 4);
657 M_FLTMOVE(var->regoff, d);
658 emit_store_dst(jd, iptr, d);
662 case ICMD_ISTORE: /* ..., value ==> ... */
663 case ICMD_ASTORE: /* op1 = local variable */
665 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
667 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
668 if (var->flags & INMEMORY) {
669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670 M_IST(s1, REG_SP, var->regoff * 4);
672 s1 = emit_load_s1(jd, iptr, var->regoff);
673 M_INTMOVE(s1, var->regoff);
677 case ICMD_LSTORE: /* ..., value ==> ... */
678 /* dst.localindex = local variable */
680 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
682 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
683 if (var->flags & INMEMORY) {
684 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
685 M_LST(s1, REG_SP, var->regoff * 4);
687 s1 = emit_load_s1(jd, iptr, var->regoff);
688 M_LNGMOVE(s1, var->regoff);
692 case ICMD_FSTORE: /* ..., value ==> ... */
693 /* dst.localindex = local variable */
695 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
697 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
698 if (var->flags & INMEMORY) {
699 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
700 M_FST(s1, REG_SP, var->regoff * 4);
702 s1 = emit_load_s1(jd, iptr, var->regoff);
703 M_FLTMOVE(s1, var->regoff);
707 case ICMD_DSTORE: /* ..., value ==> ... */
708 /* dst.localindex = local variable */
710 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
712 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
713 if (var->flags & INMEMORY) {
714 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
715 M_DST(s1, REG_SP, var->regoff * 4);
717 s1 = emit_load_s1(jd, iptr, var->regoff);
718 M_FLTMOVE(s1, var->regoff);
723 /* pop/dup/swap operations ********************************************/
725 /* attention: double and longs are only one entry in CACAO ICMDs */
727 case ICMD_POP: /* ..., value ==> ... */
728 case ICMD_POP2: /* ..., value, value ==> ... */
731 case ICMD_DUP: /* ..., a ==> ..., a, a */
733 M_COPY(iptr->s1.var, iptr->dst.var);
736 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
738 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
739 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
740 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
743 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
745 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
746 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
747 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
748 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
751 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
753 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
754 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
757 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
759 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
760 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
761 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
762 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
763 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
766 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
768 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
769 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
770 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
771 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
772 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
773 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
776 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
778 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
779 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
783 /* integer operations *************************************************/
785 case ICMD_INEG: /* ..., value ==> ..., - value */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
790 emit_store_dst(jd, iptr, d);
793 case ICMD_LNEG: /* ..., value ==> ..., - value */
795 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
797 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
798 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
799 emit_store_dst(jd, iptr, d);
802 case ICMD_I2L: /* ..., value ==> ..., value */
804 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
805 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
806 M_INTMOVE(s1, GET_LOW_REG(d));
807 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
808 emit_store_dst(jd, iptr, d);
811 case ICMD_L2I: /* ..., value ==> ..., value */
813 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
814 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
816 emit_store_dst(jd, iptr, d);
819 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
829 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
830 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
838 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
840 emit_store_dst(jd, iptr, d);
844 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
847 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 emit_store_dst(jd, iptr, d);
853 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
854 /* sx.val.i = constant */
856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
858 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
859 M_IADD_IMM(s1, iptr->sx.val.i, d);
861 ICONST(REG_ITMP2, iptr->sx.val.i);
862 M_IADD(s1, REG_ITMP2, d);
864 emit_store_dst(jd, iptr, d);
867 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
869 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
870 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
871 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
872 M_ADDC(s1, s2, GET_LOW_REG(d));
873 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
874 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
875 M_ADDE(s1, s2, GET_HIGH_REG(d));
876 emit_store_dst(jd, iptr, d);
879 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
880 /* sx.val.l = constant */
882 s3 = iptr->sx.val.l & 0xffffffff;
883 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
884 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
885 if ((s3 >= -32768) && (s3 <= 32767))
886 M_ADDIC(s1, s3, GET_LOW_REG(d));
888 ICONST(REG_ITMP2, s3);
889 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
891 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
892 s3 = iptr->sx.val.l >> 32;
894 M_ADDME(s1, GET_HIGH_REG(d));
896 M_ADDZE(s1, GET_HIGH_REG(d));
898 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
899 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
901 emit_store_dst(jd, iptr, d);
904 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
907 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
908 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
910 emit_store_dst(jd, iptr, d);
913 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
914 /* sx.val.i = constant */
916 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
917 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
918 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
919 M_IADD_IMM(s1, -iptr->sx.val.i, d);
921 ICONST(REG_ITMP2, -iptr->sx.val.i);
922 M_IADD(s1, REG_ITMP2, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
929 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
930 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
932 M_SUBC(s1, s2, GET_LOW_REG(d));
933 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
934 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
935 M_SUBE(s1, s2, GET_HIGH_REG(d));
936 emit_store_dst(jd, iptr, d);
939 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
940 /* sx.val.l = constant */
942 s3 = (-iptr->sx.val.l) & 0xffffffff;
943 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
945 if ((s3 >= -32768) && (s3 <= 32767)) {
946 M_ADDIC(s1, s3, GET_LOW_REG(d));
948 ICONST(REG_ITMP2, s3);
949 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
951 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
952 s3 = (-iptr->sx.val.l) >> 32;
954 M_ADDME(s1, GET_HIGH_REG(d));
956 M_ADDZE(s1, GET_HIGH_REG(d));
958 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
959 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
961 emit_store_dst(jd, iptr, d);
964 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
967 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
968 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
971 codegen_add_arithmeticexception_ref(cd);
972 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
973 M_CMP(REG_ITMP3, s1);
974 M_BNE(3 + (s1 != d));
976 M_BNE(1 + (s1 != d));
980 emit_store_dst(jd, iptr, d);
983 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
986 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
987 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
990 codegen_add_arithmeticexception_ref(cd);
991 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
992 M_CMP(REG_ITMP3, s1);
998 M_IDIV(s1, s2, REG_ITMP3);
999 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
1000 M_ISUB(s1, REG_ITMP3, d);
1001 emit_store_dst(jd, iptr, d);
1004 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1005 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1007 bte = iptr->sx.s23.s3.bte;
1010 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1011 M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
1013 codegen_add_arithmeticexception_ref(cd);
1015 disp = dseg_add_functionptr(cd, bte->fp);
1016 M_ALD(REG_ITMP3, REG_PV, disp);
1019 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
1020 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
1023 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1024 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
1025 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
1030 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1031 M_LNGMOVE(REG_RESULT_PACKED, d);
1032 emit_store_dst(jd, iptr, d);
1035 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1038 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1039 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1045 /* sx.val.i = constant */
1047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1048 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1049 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1050 M_IMUL_IMM(s1, iptr->sx.val.i, d);
1052 ICONST(REG_ITMP3, iptr->sx.val.i);
1053 M_IMUL(s1, REG_ITMP3, d);
1055 emit_store_dst(jd, iptr, d);
1058 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1062 M_SRA_IMM(s1, iptr->sx.val.i, d);
1064 emit_store_dst(jd, iptr, d);
1067 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1070 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1071 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1072 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1073 M_SLL(s1, REG_ITMP3, d);
1074 emit_store_dst(jd, iptr, d);
1077 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1078 /* sx.val.i = constant */
1080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1081 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1082 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
1083 emit_store_dst(jd, iptr, d);
1086 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1090 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1091 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1092 M_SRA(s1, REG_ITMP3, d);
1093 emit_store_dst(jd, iptr, d);
1096 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1097 /* sx.val.i = constant */
1099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1100 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1101 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1107 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1108 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1109 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1110 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1111 M_SRL(s1, REG_ITMP2, d);
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1116 /* sx.val.i = constant */
1118 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1119 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1120 if (iptr->sx.val.i & 0x1f)
1121 M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1131 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1134 emit_store_dst(jd, iptr, d);
1137 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1138 /* sx.val.i = constant */
1140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1142 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1143 M_AND_IMM(s1, iptr->sx.val.i, d);
1145 else if (iptr->sx.val.i == 0xffffff) {
1146 M_RLWINM(s1, 0, 8, 31, d);
1150 ICONST(REG_ITMP3, iptr->sx.val.i);
1151 M_AND(s1, REG_ITMP3, d);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1158 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1159 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1160 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1161 M_AND(s1, s2, GET_LOW_REG(d));
1162 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1163 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1164 M_AND(s1, s2, GET_HIGH_REG(d));
1165 emit_store_dst(jd, iptr, d);
1168 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1169 /* sx.val.l = constant */
1171 s3 = iptr->sx.val.l & 0xffffffff;
1172 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1173 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1174 if ((s3 >= 0) && (s3 <= 65535))
1175 M_AND_IMM(s1, s3, GET_LOW_REG(d));
1177 ICONST(REG_ITMP3, s3);
1178 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
1180 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1181 s3 = iptr->sx.val.l >> 32;
1182 if ((s3 >= 0) && (s3 <= 65535))
1183 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
1185 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1186 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1192 /* sx.val.i = constant */
1194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1195 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1196 M_MOV(s1, REG_ITMP2);
1198 M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
1199 if (iptr->sx.val.i >= 32768) {
1200 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
1201 M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
1202 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1205 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
1208 int b=0, m = iptr->sx.val.i;
1211 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1213 M_ISUB(s1, REG_ITMP2, d);
1214 emit_store_dst(jd, iptr, d);
1217 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1219 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1220 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1221 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1223 emit_store_dst(jd, iptr, d);
1226 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1227 /* sx.val.i = constant */
1229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1230 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1231 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1232 M_OR_IMM(s1, iptr->sx.val.i, d);
1234 ICONST(REG_ITMP3, iptr->sx.val.i);
1235 M_OR(s1, REG_ITMP3, d);
1237 emit_store_dst(jd, iptr, d);
1240 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1242 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1243 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1244 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1245 M_OR(s1, s2, GET_LOW_REG(d));
1246 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1247 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1248 M_OR(s1, s2, GET_HIGH_REG(d));
1249 emit_store_dst(jd, iptr, d);
1252 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1253 /* sx.val.l = constant */
1255 s3 = iptr->sx.val.l & 0xffffffff;
1256 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1257 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1258 if ((s3 >= 0) && (s3 <= 65535))
1259 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1261 ICONST(REG_ITMP3, s3);
1262 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1264 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1265 s3 = iptr->sx.val.l >> 32;
1266 if ((s3 >= 0) && (s3 <= 65535))
1267 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1269 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1270 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1272 emit_store_dst(jd, iptr, d);
1275 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1277 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1278 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1279 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1285 /* sx.val.i = constant */
1287 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1288 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1289 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1290 M_XOR_IMM(s1, iptr->sx.val.i, d);
1292 ICONST(REG_ITMP3, iptr->sx.val.i);
1293 M_XOR(s1, REG_ITMP3, d);
1295 emit_store_dst(jd, iptr, d);
1298 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1300 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1301 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1302 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1303 M_XOR(s1, s2, GET_LOW_REG(d));
1304 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1305 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1306 M_XOR(s1, s2, GET_HIGH_REG(d));
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1311 /* sx.val.l = constant */
1313 s3 = iptr->sx.val.l & 0xffffffff;
1314 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1315 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1316 if ((s3 >= 0) && (s3 <= 65535))
1317 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1319 ICONST(REG_ITMP3, s3);
1320 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1322 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1323 s3 = iptr->sx.val.l >> 32;
1324 if ((s3 >= 0) && (s3 <= 65535))
1325 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1327 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1328 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1330 emit_store_dst(jd, iptr, d);
1333 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1334 /*******************************************************************
1335 TODO: CHANGE THIS TO A VERSION THAT WORKS !!!
1336 *******************************************************************/
1337 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1338 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1339 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1341 int tempreg = false;
1345 if (iptr->s1.var->flags & INMEMORY) {
1346 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1348 tempreg = tempreg || (d == GET_HIGH_REG(iptr->s1.var->regoff))
1349 || (d == GET_LOW_REG(iptr->s1.var->regoff));
1351 if (iptr->sx.s23.s2.var->flags & INMEMORY) {
1352 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1354 tempreg = tempreg || (d == GET_HIGH_REG(iptr->sx.s23.s2.var->regoff))
1355 || (d == GET_LOW_REG(iptr->sx.s23.s2.var->regoff));
1358 dreg = tempreg ? REG_ITMP1 : d;
1359 M_IADD_IMM(REG_ZERO, 1, dreg);
1364 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1365 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1369 M_IADD_IMM(dreg, -1, dreg);
1370 M_IADD_IMM(dreg, -1, dreg);
1371 gen_resolvebranch(br1, br1, cd->mcodeptr);
1372 gen_resolvebranch(br1 + 1 * 4, br1 + 1 * 4, cd->mcodeptr - 2 * 4);
1375 emit_store_dst(jd, iptr, d);
1378 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1379 /* s1.localindex = variable, sx.val.i = constant*/
1381 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1382 if (var->flags & INMEMORY) {
1384 M_ILD(s1, REG_SP, var->regoff * 4);
1388 u4 m = iptr->sx.val.i;
1392 M_ADDIS(s1, m >> 16, s1);
1394 M_IADD_IMM(s1, m & 0xffff, s1);
1396 if (var->flags & INMEMORY)
1397 M_IST(s1, REG_SP, var->regoff * 4);
1401 /* floating operations ************************************************/
1403 case ICMD_FNEG: /* ..., value ==> ..., - value */
1405 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1406 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1408 emit_store_dst(jd, iptr, d);
1411 case ICMD_DNEG: /* ..., value ==> ..., - value */
1413 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1414 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1416 emit_store_dst(jd, iptr, d);
1419 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1421 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1422 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1423 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1430 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1431 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1432 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1434 emit_store_dst(jd, iptr, d);
1437 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1439 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1443 emit_store_dst(jd, iptr, d);
1446 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1448 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1449 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1450 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1452 emit_store_dst(jd, iptr, d);
1455 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1457 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1458 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1459 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1461 emit_store_dst(jd, iptr, d);
1464 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1466 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1467 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1468 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1470 emit_store_dst(jd, iptr, d);
1473 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1475 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1476 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1477 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1479 emit_store_dst(jd, iptr, d);
1482 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1484 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1485 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1486 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1488 emit_store_dst(jd, iptr, d);
1491 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1494 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1495 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1497 disp = dseg_add_float(cd, 0.0);
1498 M_FLD(REG_FTMP2, REG_PV, disp);
1499 M_FCMPU(s1, REG_FTMP2);
1501 disp = dseg_add_unique_s4(cd, 0);
1502 M_CVTDL_C(s1, REG_FTMP1);
1503 M_LDA(REG_ITMP1, REG_PV, disp);
1504 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1505 M_ILD(d, REG_PV, disp);
1506 emit_store_dst(jd, iptr, d);
1509 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1511 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1512 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1514 emit_store_dst(jd, iptr, d);
1517 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1519 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1520 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1522 emit_store_dst(jd, iptr, d);
1525 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1526 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1529 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1533 M_IADD_IMM(REG_ZERO, -1, d);
1536 M_IADD_IMM(REG_ZERO, 0, d);
1538 M_IADD_IMM(REG_ZERO, 1, d);
1539 emit_store_dst(jd, iptr, d);
1542 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1543 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1545 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1546 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1549 M_IADD_IMM(REG_ZERO, 1, d);
1552 M_IADD_IMM(REG_ZERO, 0, d);
1554 M_IADD_IMM(REG_ZERO, -1, d);
1555 emit_store_dst(jd, iptr, d);
1558 case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */
1559 case ICMD_IF_DCMPEQ:
1561 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1566 codegen_addreference(cd, iptr->dst.block);
1569 case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */
1570 case ICMD_IF_DCMPNE:
1572 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1573 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1576 codegen_addreference(cd, iptr->dst.block);
1578 codegen_addreference(cd, iptr->dst.block);
1582 case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */
1583 case ICMD_IF_DCMPL_LT:
1585 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1586 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1589 codegen_addreference(cd, iptr->dst.block);
1591 codegen_addreference(cd, iptr->dst.block);
1594 case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */
1595 case ICMD_IF_DCMPL_GT:
1597 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1598 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1602 codegen_addreference(cd, iptr->dst.block);
1605 case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */
1606 case ICMD_IF_DCMPL_LE:
1608 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1609 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1612 codegen_addreference(cd, iptr->dst.block);
1614 codegen_addreference(cd, iptr->dst.block);
1617 case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */
1618 case ICMD_IF_DCMPL_GE:
1620 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1621 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1625 codegen_addreference(cd, iptr->dst.block);
1628 case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */
1629 case ICMD_IF_DCMPG_LT:
1631 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1632 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1636 codegen_addreference(cd, iptr->dst.block);
1639 case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */
1640 case ICMD_IF_DCMPG_GT:
1642 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1643 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1646 codegen_addreference(cd, iptr->dst.block);
1648 codegen_addreference(cd, iptr->dst.block);
1651 case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */
1652 case ICMD_IF_DCMPG_LE:
1654 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1655 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1659 codegen_addreference(cd, iptr->dst.block);
1662 case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */
1663 case ICMD_IF_DCMPG_GE:
1665 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1666 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1669 codegen_addreference(cd, iptr->dst.block);
1671 codegen_addreference(cd, iptr->dst.block);
1675 /* memory operations **************************************************/
1677 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1680 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1681 gen_nullptr_check(s1);
1682 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1683 emit_store_dst(jd, iptr, d);
1686 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1689 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1691 if (INSTRUCTION_MUST_CHECK(iptr)) {
1692 gen_nullptr_check(s1);
1695 M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1696 M_LBZX(d, s1, REG_ITMP2);
1698 emit_store_dst(jd, iptr, d);
1701 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1704 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1705 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1706 if (INSTRUCTION_MUST_CHECK(iptr)) {
1707 gen_nullptr_check(s1);
1710 M_SLL_IMM(s2, 1, REG_ITMP2);
1711 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1712 M_LHZX(d, s1, REG_ITMP2);
1713 emit_store_dst(jd, iptr, d);
1716 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1719 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1721 if (INSTRUCTION_MUST_CHECK(iptr)) {
1722 gen_nullptr_check(s1);
1725 M_SLL_IMM(s2, 1, REG_ITMP2);
1726 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1727 M_LHAX(d, s1, REG_ITMP2);
1728 emit_store_dst(jd, iptr, d);
1731 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1734 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1736 if (INSTRUCTION_MUST_CHECK(iptr)) {
1737 gen_nullptr_check(s1);
1740 M_SLL_IMM(s2, 2, REG_ITMP2);
1741 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1742 M_LWZX(d, s1, REG_ITMP2);
1743 emit_store_dst(jd, iptr, d);
1746 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1751 if (INSTRUCTION_MUST_CHECK(iptr)) {
1752 gen_nullptr_check(s1);
1755 M_SLL_IMM(s2, 3, REG_ITMP2);
1756 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1757 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1758 emit_store_dst(jd, iptr, d);
1761 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1764 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1765 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1766 if (INSTRUCTION_MUST_CHECK(iptr)) {
1767 gen_nullptr_check(s1);
1770 M_SLL_IMM(s2, 2, REG_ITMP2);
1771 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1772 M_LFSX(d, s1, REG_ITMP2);
1773 emit_store_dst(jd, iptr, d);
1776 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1779 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1780 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1781 if (INSTRUCTION_MUST_CHECK(iptr)) {
1782 gen_nullptr_check(s1);
1785 M_SLL_IMM(s2, 3, REG_ITMP2);
1786 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1787 M_LFDX(d, s1, REG_ITMP2);
1788 emit_store_dst(jd, iptr, d);
1791 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1795 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1796 if (INSTRUCTION_MUST_CHECK(iptr)) {
1797 gen_nullptr_check(s1);
1800 M_SLL_IMM(s2, 2, REG_ITMP2);
1801 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1802 M_LWZX(d, s1, REG_ITMP2);
1803 emit_store_dst(jd, iptr, d);
1807 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1810 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1811 if (INSTRUCTION_MUST_CHECK(iptr)) {
1812 gen_nullptr_check(s1);
1815 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1816 M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1817 M_STBX(s3, s1, REG_ITMP2);
1820 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1823 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1824 if (INSTRUCTION_MUST_CHECK(iptr)) {
1825 gen_nullptr_check(s1);
1828 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1829 M_SLL_IMM(s2, 1, REG_ITMP2);
1830 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1831 M_STHX(s3, s1, REG_ITMP2);
1834 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1837 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1838 if (INSTRUCTION_MUST_CHECK(iptr)) {
1839 gen_nullptr_check(s1);
1842 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1843 M_SLL_IMM(s2, 1, REG_ITMP2);
1844 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1845 M_STHX(s3, s1, REG_ITMP2);
1848 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1850 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1851 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1852 if (INSTRUCTION_MUST_CHECK(iptr)) {
1853 gen_nullptr_check(s1);
1856 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1857 M_SLL_IMM(s2, 2, REG_ITMP2);
1858 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1859 M_STWX(s3, s1, REG_ITMP2);
1862 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1866 if (INSTRUCTION_MUST_CHECK(iptr)) {
1867 gen_nullptr_check(s1);
1870 s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1871 M_SLL_IMM(s2, 3, REG_ITMP2);
1872 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
1873 M_STWX(s3, s1, REG_ITMP2);
1874 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1875 s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1876 M_STWX(s3, s1, REG_ITMP2);
1879 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1883 if (INSTRUCTION_MUST_CHECK(iptr)) {
1884 gen_nullptr_check(s1);
1887 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1888 M_SLL_IMM(s2, 2, REG_ITMP2);
1889 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1890 M_STFSX(s3, s1, REG_ITMP2);
1893 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1896 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1897 if (INSTRUCTION_MUST_CHECK(iptr)) {
1898 gen_nullptr_check(s1);
1901 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1902 M_SLL_IMM(s2, 3, REG_ITMP2);
1903 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1904 M_STFDX(s3, s1, REG_ITMP2);
1907 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1909 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
1910 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1911 if (INSTRUCTION_MUST_CHECK(iptr)) {
1912 gen_nullptr_check(s1);
1915 s3 = emit_load_s3(jd, iptr, rd->argintregs[1]);
1917 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1918 M_ALD(REG_ITMP3, REG_PV, disp);
1921 M_INTMOVE(s1, rd->argintregs[0]);
1922 M_INTMOVE(s3, rd->argintregs[1]);
1927 codegen_add_arraystoreexception_ref(cd);
1929 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1930 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1931 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1932 M_SLL_IMM(s2, 2, REG_ITMP2);
1933 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1934 M_STWX(s3, s1, REG_ITMP2);
1938 case ICMD_GETSTATIC: /* ... ==> ..., value */
1940 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1941 unresolved_field *uf = iptr->sx.s23.s3.uf;
1943 fieldtype = uf->fieldref->parseddesc.fd->type;
1944 disp = dseg_add_unique_address(cd, uf);
1946 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1948 if (opt_showdisassemble)
1952 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1954 fieldtype = fi->type;
1955 disp = dseg_add_address(cd, &(fi->value));
1957 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1958 codegen_addpatchref(cd, PATCHER_initialize_class,
1961 if (opt_showdisassemble)
1966 M_ALD(REG_ITMP1, REG_PV, disp);
1967 switch (fieldtype) {
1969 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1970 M_ILD_INTERN(d, REG_ITMP1, 0);
1973 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1974 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1975 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1978 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1979 M_ALD_INTERN(d, REG_ITMP1, 0);
1982 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1983 M_FLD_INTERN(d, REG_ITMP1, 0);
1986 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1987 M_DLD_INTERN(d, REG_ITMP1, 0);
1990 emit_store_dst(jd, iptr, d);
1993 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1995 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1996 unresolved_field *uf = iptr->sx.s23.s3.uf;
1998 fieldtype = uf->fieldref->parseddesc.fd->type;
1999 disp = dseg_add_unique_address(cd, uf);
2001 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2003 if (opt_showdisassemble)
2007 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2009 fieldtype = fi->type;
2010 disp = dseg_add_address(cd, &(fi->value));
2012 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2013 codegen_addpatchref(cd, PATCHER_initialize_class,
2016 if (opt_showdisassemble)
2021 M_ALD(REG_ITMP1, REG_PV, disp);
2022 switch (fieldtype) {
2024 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2025 M_IST_INTERN(s1, REG_ITMP1, 0);
2028 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2029 M_LST_INTERN(s1, REG_ITMP1, 0);
2032 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2033 M_AST_INTERN(s1, REG_ITMP1, 0);
2036 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2037 M_FST_INTERN(s1, REG_ITMP1, 0);
2040 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2041 M_DST_INTERN(s1, REG_ITMP1, 0);
2047 case ICMD_GETFIELD: /* ... ==> ..., value */
2049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2050 gen_nullptr_check(s1);
2052 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2053 unresolved_field *uf = iptr->sx.s23.s3.uf;
2055 fieldtype = uf->fieldref->parseddesc.fd->type;
2057 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2059 if (opt_showdisassemble)
2065 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2066 fieldtype = fi->type;
2070 switch (fieldtype) {
2072 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2077 if (GET_HIGH_REG(d) == s1) {
2078 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2079 M_ILD(GET_HIGH_REG(d), s1, disp);
2082 M_ILD(GET_HIGH_REG(d), s1, disp);
2083 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2087 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2091 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2095 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2099 emit_store_dst(jd, iptr, d);
2102 case ICMD_PUTFIELD: /* ..., value ==> ... */
2104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2105 gen_nullptr_check(s1);
2107 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2108 if (IS_2_WORD_TYPE(fieldtype))
2109 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2111 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2114 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2116 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2117 unresolved_field *uf = iptr->sx.s23.s3.uf;
2119 fieldtype = uf->fieldref->parseddesc.fd->type;
2121 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2123 if (opt_showdisassemble)
2129 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2130 fieldtype = fi->type;
2134 switch (fieldtype) {
2136 M_IST(s2, s1, disp);
2139 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
2140 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
2143 M_AST(s2, s1, disp);
2146 M_FST(s2, s1, disp);
2149 M_DST(s2, s1, disp);
2155 /* branch operations **************************************************/
2157 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2160 M_INTMOVE(s1, REG_ITMP1_XPTR);
2162 #ifdef ENABLE_VERIFIER
2163 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2164 unresolved_class *uc = iptr->sx.s23.s2.uc;
2166 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2168 if (opt_showdisassemble)
2171 #endif /* ENABLE_VERIFIER */
2173 disp = dseg_add_functionptr(cd, asm_handle_exception);
2174 M_ALD(REG_ITMP2, REG_PV, disp);
2177 if (jd->isleafmethod)
2178 M_MFLR(REG_ITMP3); /* save LR */
2180 M_BL(0); /* get current PC */
2181 M_MFLR(REG_ITMP2_XPC);
2183 if (jd->isleafmethod)
2184 M_MTLR(REG_ITMP3); /* restore LR */
2186 M_RTS; /* jump to CTR */
2190 case ICMD_GOTO: /* ... ==> ... */
2192 codegen_addreference(cd, iptr->dst.block);
2196 case ICMD_JSR: /* ... ==> ... */
2198 if (jd->isleafmethod)
2203 M_IADD_IMM(REG_ITMP1, jd->isleafmethod ? 4*4 : 3*4, REG_ITMP1);
2205 if (jd->isleafmethod)
2209 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2212 case ICMD_RET: /* ... ==> ... */
2213 /* s1.localindex = local variable */
2215 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
2216 if (var->flags & INMEMORY) {
2217 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2220 M_MTCTR(var->regoff);
2226 case ICMD_IFNULL: /* ..., value ==> ... */
2228 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2231 codegen_addreference(cd, iptr->dst.block);
2234 case ICMD_IFNONNULL: /* ..., value ==> ... */
2236 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2239 codegen_addreference(cd, iptr->dst.block);
2247 case ICMD_IFEQ: /* ..., value ==> ... */
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2251 M_CMPI(s1, iptr->sx.val.i);
2253 ICONST(REG_ITMP2, iptr->sx.val.i);
2254 M_CMP(s1, REG_ITMP2);
2256 switch (iptr->opc) {
2276 codegen_addreference(cd, iptr->dst.block);
2280 case ICMD_IF_LEQ: /* ..., value ==> ... */
2282 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2283 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2284 if (iptr->sx.val.l == 0) {
2285 M_OR_TST(s1, s2, REG_ITMP3);
2287 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2288 M_XOR_IMM(s2, 0, REG_ITMP2);
2289 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
2290 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2293 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2294 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2295 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2296 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2297 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2300 codegen_addreference(cd, iptr->dst.block);
2303 case ICMD_IF_LLT: /* ..., value ==> ... */
2304 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2305 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2306 if (iptr->sx.val.l == 0) {
2307 /* if high word is less than zero, the whole long is too */
2310 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2313 codegen_addreference(cd, iptr->dst.block);
2315 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2318 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2319 M_CMP(s2, REG_ITMP3);
2321 codegen_addreference(cd, iptr->dst.block);
2323 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2324 M_CMPU(s1, REG_ITMP3);
2327 codegen_addreference(cd, iptr->dst.block);
2330 case ICMD_IF_LLE: /* ..., value ==> ... */
2332 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2333 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2334 /* if (iptr->sx.val.l == 0) { */
2335 /* M_OR(s1, s2, REG_ITMP3); */
2336 /* M_CMPI(REG_ITMP3, 0); */
2339 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2342 codegen_addreference(cd, iptr->dst.block);
2344 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2347 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2348 M_CMP(s2, REG_ITMP3);
2350 codegen_addreference(cd, iptr->dst.block);
2352 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2353 M_CMPU(s1, REG_ITMP3);
2356 codegen_addreference(cd, iptr->dst.block);
2359 case ICMD_IF_LNE: /* ..., value ==> ... */
2361 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2362 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2363 if (iptr->sx.val.l == 0) {
2364 M_OR_TST(s1, s2, REG_ITMP3);
2366 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2367 M_XOR_IMM(s2, 0, REG_ITMP2);
2368 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
2369 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2372 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2373 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2374 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2375 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2376 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2379 codegen_addreference(cd, iptr->dst.block);
2382 case ICMD_IF_LGT: /* ..., value ==> ... */
2384 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2385 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2386 /* if (iptr->sx.val.l == 0) { */
2387 /* M_OR(s1, s2, REG_ITMP3); */
2388 /* M_CMPI(REG_ITMP3, 0); */
2391 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2394 codegen_addreference(cd, iptr->dst.block);
2396 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2399 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2400 M_CMP(s2, REG_ITMP3);
2402 codegen_addreference(cd, iptr->dst.block);
2404 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2405 M_CMPU(s1, REG_ITMP3);
2408 codegen_addreference(cd, iptr->dst.block);
2411 case ICMD_IF_LGE: /* ..., value ==> ... */
2413 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2414 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2415 if (iptr->sx.val.l == 0) {
2416 /* if high word is greater equal zero, the whole long is too */
2419 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2422 codegen_addreference(cd, iptr->dst.block);
2424 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2427 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2428 M_CMP(s2, REG_ITMP3);
2430 codegen_addreference(cd, iptr->dst.block);
2432 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2433 M_CMPU(s1, REG_ITMP3);
2436 codegen_addreference(cd, iptr->dst.block);
2439 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2440 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2442 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2443 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2446 codegen_addreference(cd, iptr->dst.block);
2449 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2451 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2452 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2454 /* load low-bits before the branch, so we know the distance */
2455 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2456 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2460 codegen_addreference(cd, iptr->dst.block);
2463 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2464 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2466 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2467 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2470 codegen_addreference(cd, iptr->dst.block);
2473 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2475 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2476 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2479 codegen_addreference(cd, iptr->dst.block);
2480 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2481 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2484 codegen_addreference(cd, iptr->dst.block);
2487 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2490 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2493 codegen_addreference(cd, iptr->dst.block);
2496 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2498 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2499 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2502 codegen_addreference(cd, iptr->dst.block);
2503 /* load low-bits before the branch, so we know the distance */
2504 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2505 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2509 codegen_addreference(cd, iptr->dst.block);
2512 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2515 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2518 codegen_addreference(cd, iptr->dst.block);
2521 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2523 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2524 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2527 codegen_addreference(cd, iptr->dst.block);
2528 /* load low-bits before the branch, so we know the distance */
2529 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2530 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2534 codegen_addreference(cd, iptr->dst.block);
2537 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2543 codegen_addreference(cd, iptr->dst.block);
2546 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2548 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2549 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2552 codegen_addreference(cd, iptr->dst.block);
2553 /* load low-bits before the branch, so we know the distance */
2554 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2555 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2559 codegen_addreference(cd, iptr->dst.block);
2562 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2565 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2568 codegen_addreference(cd, iptr->dst.block);
2571 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2573 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2574 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2577 codegen_addreference(cd, iptr->dst.block);
2578 /* load low-bits before the branch, so we know the distance */
2579 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2580 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2584 codegen_addreference(cd, iptr->dst.block);
2587 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2589 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2590 M_INTMOVE(s1, REG_RESULT);
2591 goto nowperformreturn;
2593 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2595 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2596 M_INTMOVE(s1, REG_RESULT);
2598 #ifdef ENABLE_VERIFIER
2599 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2600 unresolved_class *uc = iptr->sx.s23.s2.uc;
2602 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2604 if (opt_showdisassemble)
2607 #endif /* ENABLE_VERIFIER */
2608 goto nowperformreturn;
2610 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2612 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2613 M_LNGMOVE(s1, REG_RESULT_PACKED);
2614 goto nowperformreturn;
2616 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2619 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2620 M_FLTMOVE(s1, REG_FRESULT);
2621 goto nowperformreturn;
2623 case ICMD_RETURN: /* ... ==> ... */
2629 p = cd->stackframesize;
2631 /* call trace function */
2633 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2634 emit_verbosecall_exit(jd);
2636 #if defined(ENABLE_THREADS)
2637 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2638 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2639 M_ALD(REG_ITMP3, REG_PV, disp);
2642 /* we need to save the proper return value */
2644 switch (iptr->opc) {
2646 M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2650 M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2653 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2656 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2660 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 4);
2663 /* and now restore the proper return value */
2665 switch (iptr->opc) {
2667 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2671 M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2674 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2677 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2683 /* restore return address */
2685 if (!jd->isleafmethod) {
2686 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2687 may have a displacement overflow. */
2689 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
2693 /* restore saved registers */
2695 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2696 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2698 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2699 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2702 /* deallocate stack */
2704 if (cd->stackframesize)
2705 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4);
2713 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2716 branch_target_t *table;
2718 table = iptr->dst.table;
2720 l = iptr->sx.s23.s2.tablelow;
2721 i = iptr->sx.s23.s3.tablehigh;
2723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2725 M_INTMOVE(s1, REG_ITMP1);
2726 else if (l <= 32768)
2727 M_LDA(REG_ITMP1, s1, -l);
2729 ICONST(REG_ITMP2, l);
2730 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2737 M_CMPUI(REG_ITMP1, i - 1);
2739 codegen_addreference(cd, table[0].block);
2741 /* build jump table top down and use address of lowest entry */
2746 dseg_add_target(cd, table->block);
2750 /* length of dataseg after last dseg_add_target is used by load */
2752 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2753 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2754 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2762 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2765 lookup_target_t *lookup;
2767 lookup = iptr->dst.lookup;
2769 i = iptr->sx.s23.s2.lookupcount;
2771 MCODECHECK((i<<2)+8);
2772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2775 if ((lookup->value >= -32768) && (lookup->value <= 32767)) {
2776 M_CMPI(s1, lookup->value);
2779 disp = dseg_add_s4(cd, lookup->value);
2780 M_ILD(REG_ITMP2, REG_PV, disp);
2781 M_CMP(s1, REG_ITMP2);
2784 codegen_addreference(cd, lookup->target.block);
2789 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2796 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2798 bte = iptr->sx.s23.s3.bte;
2802 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2804 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2805 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2806 case ICMD_INVOKEINTERFACE:
2808 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2809 md = iptr->sx.s23.s3.um->methodref->parseddesc.md;
2813 lm = iptr->sx.s23.s3.fmiref->p.method;
2814 md = lm->parseddesc;
2818 s3 = md->paramcount;
2820 MCODECHECK((s3 << 1) + 64);
2822 /* copy arguments to registers or stack location */
2824 for (s3 = s3 - 1; s3 >= 0; s3--) {
2825 src = iptr->sx.s23.s2.args[s3];
2827 if (src->varkind == ARGVAR)
2830 if (IS_INT_LNG_TYPE(src->type)) {
2831 if (!md->params[s3].inmemory) {
2832 if (IS_2_WORD_TYPE(src->type)) {
2834 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
2835 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]);
2836 d = emit_load(jd, iptr, src, s1);
2840 s1 = rd->argintregs[md->params[s3].regoff];
2841 d = emit_load(jd, iptr, src, s1);
2846 if (IS_2_WORD_TYPE(src->type)) {
2847 d = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
2848 M_LST(d, REG_SP, md->params[s3].regoff * 4);
2851 d = emit_load(jd, iptr, src, REG_ITMP1);
2852 M_IST(d, REG_SP, md->params[s3].regoff * 4);
2857 if (!md->params[s3].inmemory) {
2858 s1 = rd->argfltregs[md->params[s3].regoff];
2859 d = emit_load(jd, iptr, src, s1);
2863 d = emit_load(jd, iptr, src, REG_FTMP1);
2864 if (IS_2_WORD_TYPE(src->type))
2865 M_DST(d, REG_SP, md->params[s3].regoff * 4);
2867 M_FST(d, REG_SP, md->params[s3].regoff * 4);
2872 switch (iptr->opc) {
2874 disp = dseg_add_functionptr(cd, bte->fp);
2875 d = md->returntype.type;
2877 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
2880 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2882 M_LDA(REG_PV, REG_ITMP1, -disp);
2884 if (INSTRUCTION_MUST_CHECK(iptr)) {
2885 M_CMPI(REG_RESULT, 0);
2887 codegen_add_fillinstacktrace_ref(cd);
2891 case ICMD_INVOKESPECIAL:
2892 gen_nullptr_check(rd->argintregs[0]);
2893 M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */
2896 case ICMD_INVOKESTATIC:
2898 unresolved_method *um = iptr->sx.s23.s3.um;
2900 disp = dseg_add_unique_address(cd, um);
2902 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2905 if (opt_showdisassemble)
2908 d = md->returntype.type;
2911 disp = dseg_add_address(cd, lm->stubroutine);
2912 d = md->returntype.type;
2915 M_ALD(REG_PV, REG_PV, disp);
2918 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2920 M_LDA(REG_PV, REG_ITMP1, -disp);
2923 case ICMD_INVOKEVIRTUAL:
2924 gen_nullptr_check(rd->argintregs[0]);
2927 unresolved_method *um = iptr->sx.s23.s3.um;
2929 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2931 if (opt_showdisassemble)
2935 d = md->returntype.type;
2938 s1 = OFFSET(vftbl_t, table[0]) +
2939 sizeof(methodptr) * lm->vftblindex;
2940 d = md->returntype.type;
2943 M_ALD(REG_METHODPTR, rd->argintregs[0],
2944 OFFSET(java_objectheader, vftbl));
2945 M_ALD(REG_PV, REG_METHODPTR, s1);
2948 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2950 M_LDA(REG_PV, REG_ITMP1, -disp);
2953 case ICMD_INVOKEINTERFACE:
2954 gen_nullptr_check(rd->argintregs[0]);
2957 unresolved_method *um = iptr->sx.s23.s3.um;
2959 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2961 if (opt_showdisassemble)
2966 d = md->returntype.type;
2969 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2970 sizeof(methodptr*) * lm->class->index;
2972 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2974 d = md->returntype.type;
2977 M_ALD(REG_METHODPTR, rd->argintregs[0],
2978 OFFSET(java_objectheader, vftbl));
2979 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2980 M_ALD(REG_PV, REG_METHODPTR, s2);
2983 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2985 M_LDA(REG_PV, REG_ITMP1, -disp);
2989 /* d contains return type */
2991 if (d != TYPE_VOID) {
2992 if (IS_INT_LNG_TYPE(d)) {
2993 if (IS_2_WORD_TYPE(d)) {
2994 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2995 M_LNGMOVE(REG_RESULT_PACKED, s1);
2998 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2999 M_INTMOVE(REG_RESULT, s1);
3003 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3004 M_FLTMOVE(REG_FRESULT, s1);
3006 emit_store_dst(jd, iptr, s1);
3011 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3012 /* val.a: (classinfo*) superclass */
3014 /* superclass is an interface:
3016 * OK if ((sub == NULL) ||
3017 * (sub->vftbl->interfacetablelength > super->index) &&
3018 * (sub->vftbl->interfacetable[-super->index] != NULL));
3020 * superclass is a class:
3022 * OK if ((sub == NULL) || (0
3023 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3024 * super->vftbl->diffvall));
3027 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3028 /* object type cast-check */
3033 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3038 super = iptr->sx.s23.s3.c.cls;
3039 superindex = super->index;
3042 #if defined(ENABLE_THREADS)
3043 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3048 /* calculate interface checkcast code size */
3052 s2 += (opt_showdisassemble ? 1 : 0);
3054 /* calculate class checkcast code size */
3056 s3 = 8 + (s1 == REG_ITMP1);
3058 s3 += (opt_showdisassemble ? 1 : 0);
3060 /* if class is not resolved, check which code to call */
3062 if (super == NULL) {
3064 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3066 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3068 codegen_addpatchref(cd,
3069 PATCHER_resolve_classref_to_flags,
3070 iptr->sx.s23.s3.c.ref,
3073 if (opt_showdisassemble)
3076 M_ILD(REG_ITMP2, REG_PV, disp);
3077 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3081 /* interface checkcast code */
3083 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3084 if (super == NULL) {
3085 codegen_addpatchref(cd,
3086 PATCHER_checkcast_instanceof_interface,
3087 iptr->sx.s23.s3.c.ref,
3090 if (opt_showdisassemble)
3098 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3099 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3100 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3102 codegen_add_classcastexception_ref(cd, s1);
3103 M_ALD(REG_ITMP3, REG_ITMP2,
3104 OFFSET(vftbl_t, interfacetable[0]) -
3105 superindex * sizeof(methodptr*));
3108 codegen_add_classcastexception_ref(cd, s1);
3114 /* class checkcast code */
3116 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3117 if (super == NULL) {
3118 disp = dseg_add_unique_address(cd, NULL);
3120 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3121 iptr->sx.s23.s3.c.ref,
3124 if (opt_showdisassemble)
3128 disp = dseg_add_address(cd, super->vftbl);
3134 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3135 #if defined(ENABLE_THREADS)
3136 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3138 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3139 M_ALD(REG_ITMP2, REG_PV, disp);
3140 if (s1 != REG_ITMP1) {
3141 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
3142 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3143 #if defined(ENABLE_THREADS)
3144 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3146 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
3148 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3149 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3150 M_ALD(REG_ITMP2, REG_PV, disp);
3151 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3152 #if defined(ENABLE_THREADS)
3153 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3156 M_CMPU(REG_ITMP3, REG_ITMP2);
3158 codegen_add_classcastexception_ref(cd, s1);
3160 d = codegen_reg_of_dst(jd, iptr, s1);
3163 /* array type cast-check */
3165 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
3166 M_INTMOVE(s1, rd->argintregs[0]);
3168 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3169 disp = dseg_add_unique_address(cd, NULL);
3171 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3172 iptr->sx.s23.s3.c.ref,
3175 if (opt_showdisassemble)
3179 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3181 M_ALD(rd->argintregs[1], REG_PV, disp);
3182 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3183 M_ALD(REG_ITMP2, REG_PV, disp);
3188 codegen_add_classcastexception_ref(cd, s1);
3190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3191 d = codegen_reg_of_dst(jd, iptr, s1);
3194 emit_store_dst(jd, iptr, d);
3197 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3198 /* val.a: (classinfo*) superclass */
3200 /* superclass is an interface:
3202 * return (sub != NULL) &&
3203 * (sub->vftbl->interfacetablelength > super->index) &&
3204 * (sub->vftbl->interfacetable[-super->index] != NULL);
3206 * superclass is a class:
3208 * return ((sub != NULL) && (0
3209 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3210 * super->vftbl->diffvall));
3217 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3222 super = iptr->sx.s23.s3.c.cls;
3223 superindex = super->index;
3226 #if defined(ENABLE_THREADS)
3227 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3230 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3232 M_MOV(s1, REG_ITMP1);
3236 /* calculate interface instanceof code size */
3240 s2 += (opt_showdisassemble ? 1 : 0);
3242 /* calculate class instanceof code size */
3246 s3 += (opt_showdisassemble ? 1 : 0);
3250 /* if class is not resolved, check which code to call */
3252 if (super == NULL) {
3254 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3256 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3258 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
3259 iptr->sx.s23.s3.c.ref, disp);
3261 if (opt_showdisassemble)
3264 M_ILD(REG_ITMP3, REG_PV, disp);
3265 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3269 /* interface instanceof code */
3271 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3272 if (super == NULL) {
3273 codegen_addpatchref(cd,
3274 PATCHER_checkcast_instanceof_interface,
3275 iptr->sx.s23.s3.c.ref, 0);
3277 if (opt_showdisassemble)
3285 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3286 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3287 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3289 M_ALD(REG_ITMP1, REG_ITMP1,
3290 OFFSET(vftbl_t, interfacetable[0]) -
3291 superindex * sizeof(methodptr*));
3294 M_IADD_IMM(REG_ZERO, 1, d);
3300 /* class instanceof code */
3302 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3303 if (super == NULL) {
3304 disp = dseg_add_unique_address(cd, NULL);
3306 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3307 iptr->sx.s23.s3.c.ref,
3310 if (opt_showdisassemble)
3314 disp = dseg_add_address(cd, super->vftbl);
3320 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3321 M_ALD(REG_ITMP2, REG_PV, disp);
3322 #if defined(ENABLE_THREADS)
3323 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3325 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3326 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3327 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3328 #if defined(ENABLE_THREADS)
3329 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3331 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3332 M_CMPU(REG_ITMP1, REG_ITMP2);
3335 M_IADD_IMM(REG_ZERO, 1, d);
3337 emit_store_dst(jd, iptr, d);
3341 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3343 /* check for negative sizes and copy sizes to stack if necessary */
3345 MCODECHECK((iptr->s1.argcount << 1) + 64);
3347 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
3348 src = iptr->sx.s23.s2.args[s1];
3350 /* copy SAVEDVAR sizes to stack */
3352 if (src->varkind != ARGVAR) {
3353 s2 = emit_load(jd, iptr, src, REG_ITMP1);
3354 #if defined(__DARWIN__)
3355 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
3357 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
3362 /* a0 = dimension count */
3364 ICONST(rd->argintregs[0], iptr->s1.argcount);
3366 /* is patcher function set? */
3368 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3369 disp = dseg_add_unique_address(cd, NULL);
3371 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3372 iptr->sx.s23.s3.c.ref, disp);
3374 if (opt_showdisassemble)
3378 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3380 /* a1 = arraydescriptor */
3382 M_ALD(rd->argintregs[1], REG_PV, disp);
3384 /* a2 = pointer to dimensions = stack pointer */
3386 #if defined(__DARWIN__)
3387 M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 4);
3389 M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 4);
3392 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3393 M_ALD(REG_ITMP3, REG_PV, disp);
3397 /* check for exception before result assignment */
3399 M_CMPI(REG_RESULT, 0);
3401 codegen_add_fillinstacktrace_ref(cd);
3403 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3404 M_INTMOVE(REG_RESULT, d);
3405 emit_store_dst(jd, iptr, d);
3410 new_internalerror("Unknown ICMD %d during code generation",
3415 } /* for instruction */
3417 /* copy values to interface registers */
3419 src = bptr->outstack;
3420 len = bptr->outdepth;
3421 MCODECHECK(64 + len);
3422 #if defined(ENABLE_LSRA)
3427 if ((src->varkind != STACKVAR)) {
3429 if (IS_FLT_DBL_TYPE(s2)) {
3430 s1 = emit_load(jd, iptr, src, REG_FTMP1);
3431 if (!(rd->interfaces[len][s2].flags & INMEMORY))
3432 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
3434 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3437 s1 = emit_load(jd, iptr, src, REG_ITMP1);
3438 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3439 if (IS_2_WORD_TYPE(s2))
3440 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
3442 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3445 if (IS_2_WORD_TYPE(s2))
3446 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3448 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3454 } /* if (bptr -> flags >= BBREACHED) */
3455 } /* for basic block */
3457 dseg_createlinenumbertable(cd);
3459 /* generate stubs */
3461 emit_exception_stubs(jd);
3462 emit_patcher_stubs(jd);
3463 emit_replacement_stubs(jd);
3467 /* everything's ok */
3473 /* createcompilerstub **********************************************************
3475 Creates a stub routine which calls the compiler.
3477 *******************************************************************************/
3479 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3480 #define COMPILERSTUB_CODESIZE 4 * 4
3482 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3485 u1 *createcompilerstub(methodinfo *m)
3487 u1 *s; /* memory to hold the stub */
3493 s = CNEW(u1, COMPILERSTUB_SIZE);
3495 /* set data pointer and code pointer */
3498 s = s + COMPILERSTUB_DATASIZE;
3500 /* mark start of dump memory area */
3502 dumpsize = dump_size();
3504 cd = DNEW(codegendata);
3507 /* Store the codeinfo pointer in the same place as in the
3508 methodheader for compiled methods. */
3510 code = code_codeinfo_new(m);
3512 d[0] = (ptrint) asm_call_jit_compiler;
3514 d[2] = (ptrint) code;
3516 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
3517 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
3521 md_cacheflush((u1 *) d, COMPILERSTUB_SIZE);
3523 #if defined(ENABLE_STATISTICS)
3525 count_cstub_len += COMPILERSTUB_SIZE;
3528 /* release dump area */
3530 dump_release(dumpsize);
3536 /* createnativestub ************************************************************
3538 Creates a stub routine which calls a native method.
3540 *******************************************************************************/
3542 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3550 s4 i, j; /* count variables */
3555 /* get required compiler data */
3562 /* set some variables */
3565 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3567 /* calculate stackframe size */
3569 cd->stackframesize =
3570 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3571 sizeof(localref_table) / SIZEOF_VOID_P +
3572 4 + /* 4 stackframeinfo arguments (darwin)*/
3573 nmd->paramcount * 2 + /* assume all arguments are doubles */
3576 /* keep stack 16-byte aligned */
3578 cd->stackframesize = (cd->stackframesize + 3) & ~3;
3580 /* create method header */
3582 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3583 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3584 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3585 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3586 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3587 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3588 (void) dseg_addlinenumbertablesize(cd);
3589 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3594 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
3595 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
3597 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3598 emit_verbosecall_enter(jd);
3600 /* get function address (this must happen before the stackframeinfo) */
3602 funcdisp = dseg_add_functionptr(cd, f);
3604 #if !defined(WITH_STATIC_CLASSPATH)
3606 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp);
3608 if (opt_showdisassemble)
3613 /* save integer and float argument registers */
3617 for (i = 0; i < md->paramcount; i++) {
3618 t = md->paramtypes[i].type;
3620 if (IS_INT_LNG_TYPE(t)) {
3621 if (!md->params[i].inmemory) {
3622 s1 = md->params[i].regoff;
3623 if (IS_2_WORD_TYPE(t)) {
3624 M_IST(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3626 M_IST(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3628 M_IST(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3635 for (i = 0; i < md->paramcount; i++) {
3636 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3637 if (!md->params[i].inmemory) {
3638 s1 = md->params[i].regoff;
3639 M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3645 /* create native stack info */
3647 M_AADD_IMM(REG_SP, cd->stackframesize * 4, rd->argintregs[0]);
3648 M_MOV(REG_PV, rd->argintregs[1]);
3649 M_AADD_IMM(REG_SP, cd->stackframesize * 4, rd->argintregs[2]);
3650 M_ALD(rd->argintregs[3], REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3651 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3652 M_ALD(REG_ITMP1, REG_PV, disp);
3656 /* restore integer and float argument registers */
3660 for (i = 0; i < md->paramcount; i++) {
3661 t = md->paramtypes[i].type;
3663 if (IS_INT_LNG_TYPE(t)) {
3664 if (!md->params[i].inmemory) {
3665 s1 = md->params[i].regoff;
3667 if (IS_2_WORD_TYPE(t)) {
3668 M_ILD(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3670 M_ILD(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3672 M_ILD(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3679 for (i = 0; i < md->paramcount; i++) {
3680 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3681 if (!md->params[i].inmemory) {
3682 s1 = md->params[i].regoff;
3683 M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3689 /* copy or spill arguments to new locations */
3691 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3692 t = md->paramtypes[i].type;
3694 if (IS_INT_LNG_TYPE(t)) {
3695 if (!md->params[i].inmemory) {
3696 if (IS_2_WORD_TYPE(t))
3698 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
3699 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
3701 s1 = rd->argintregs[md->params[i].regoff];
3703 if (!nmd->params[j].inmemory) {
3704 if (IS_2_WORD_TYPE(t)) {
3706 rd->argintregs[GET_LOW_REG(nmd->params[j].regoff)],
3707 rd->argintregs[GET_HIGH_REG(nmd->params[j].regoff)]);
3710 s2 = rd->argintregs[nmd->params[j].regoff];
3715 s2 = nmd->params[j].regoff;
3716 if (IS_2_WORD_TYPE(t))
3717 M_LST(s1, REG_SP, s2 * 4);
3719 M_IST(s1, REG_SP, s2 * 4);
3723 s1 = md->params[i].regoff + cd->stackframesize;
3724 s2 = nmd->params[j].regoff;
3726 M_ILD(REG_ITMP1, REG_SP, s1 * 4);
3727 if (IS_2_WORD_TYPE(t))
3728 M_ILD(REG_ITMP2, REG_SP, s1 * 4 + 4);
3730 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3731 if (IS_2_WORD_TYPE(t))
3732 M_IST(REG_ITMP2, REG_SP, s2 * 4 + 4);
3736 /* We only copy spilled float arguments, as the float
3737 argument registers keep unchanged. */
3739 if (md->params[i].inmemory) {
3740 s1 = md->params[i].regoff + cd->stackframesize;
3741 s2 = nmd->params[j].regoff;
3743 if (IS_2_WORD_TYPE(t)) {
3744 M_DLD(REG_FTMP1, REG_SP, s1 * 4);
3745 M_DST(REG_FTMP1, REG_SP, s2 * 4);
3748 M_FLD(REG_FTMP1, REG_SP, s1 * 4);
3749 M_FST(REG_FTMP1, REG_SP, s2 * 4);
3755 /* put class into second argument register */
3757 if (m->flags & ACC_STATIC) {
3758 disp = dseg_add_address(cd, m->class);
3759 M_ALD(rd->argintregs[1], REG_PV, disp);
3762 /* put env into first argument register */
3764 disp = dseg_add_address(cd, _Jv_env);
3765 M_ALD(rd->argintregs[0], REG_PV, disp);
3767 /* generate the actual native call */
3769 M_ALD(REG_ITMP3, REG_PV, funcdisp);
3773 /* print call trace */
3775 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3776 emit_verbosecall_exit(jd);
3778 /* save return value */
3780 if (md->returntype.type != TYPE_VOID) {
3781 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3782 if (IS_2_WORD_TYPE(md->returntype.type))
3783 M_IST(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3784 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3787 if (IS_2_WORD_TYPE(md->returntype.type))
3788 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3790 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3794 /* remove native stackframe info */
3796 M_AADD_IMM(REG_SP, cd->stackframesize * 4, rd->argintregs[0]);
3797 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3798 M_ALD(REG_ITMP1, REG_PV, disp);
3801 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3803 /* restore return value */
3805 if (md->returntype.type != TYPE_VOID) {
3806 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3807 if (IS_2_WORD_TYPE(md->returntype.type))
3808 M_ILD(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3809 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3812 if (IS_2_WORD_TYPE(md->returntype.type))
3813 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3815 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3819 M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3820 M_MTLR(REG_ITMP2_XPC);
3821 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4); /* remove stackframe */
3823 /* check for exception */
3825 M_TST(REG_ITMP1_XPTR);
3826 M_BNE(1); /* if no exception then return */
3830 /* handle exception */
3832 M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3834 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3835 M_ALD(REG_ITMP3, REG_PV, disp);
3839 /* generate patcher stubs */
3841 emit_patcher_stubs(jd);
3845 return code->entrypoint;
3850 * These are local overrides for various environment variables in Emacs.
3851 * Please do not remove this and leave it at the end of the file, where
3852 * Emacs will automagically detect them.
3853 * ---------------------------------------------------------------------
3856 * indent-tabs-mode: t
3860 * vim:noexpandtab:sw=4:ts=4: