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 5323 2006-09-05 16:45:24Z edwin $
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;
103 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
104 builtintable_entry *bte;
106 rplpoint *replacementpoint;
108 /* get required compiler data */
115 /* prevent compiler warnings */
127 /* space to save used callee saved registers */
129 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
130 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
132 cd->stackframesize = rd->memuse + savedregs_num;
134 #if defined(ENABLE_THREADS)
135 /* Space to save argument of monitor_enter and Return Values to
136 survive monitor_exit. The stack position for the argument can
137 not be shared with place to save the return register on PPC,
138 since both values reside in R3. */
140 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
141 /* reserve 2 slots for long/double return values for monitorexit */
143 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
144 cd->stackframesize += 3;
146 cd->stackframesize += 2;
151 /* create method header */
153 /* align stack to 16-bytes */
155 if (!jd->isleafmethod || JITDATA_HAS_FLAG_VERBOSECALL(jd))
156 cd->stackframesize = (cd->stackframesize + 3) & ~3;
158 else if (jd->isleafmethod && (cd->stackframesize == LA_SIZE_IN_POINTERS))
159 cd->stackframesize = 0;
161 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
162 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
164 #if defined(ENABLE_THREADS)
165 /* IsSync contains the offset relative to the stack pointer for the
166 argument of monitor_exit used in the exception handler. Since the
167 offset could be zero and give a wrong meaning of the flag it is
171 if (checksync && (m->flags & ACC_SYNCHRONIZED))
172 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync */
175 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
177 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
178 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
179 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
181 dseg_addlinenumbertablesize(cd);
183 (void) dseg_add_unique_s4(cd, cd->exceptiontablelength); /* ExTableSize */
185 /* create exception table */
187 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
188 dseg_add_target(cd, ex->start);
189 dseg_add_target(cd, ex->end);
190 dseg_add_target(cd, ex->handler);
191 (void) dseg_add_unique_address(cd, ex->catchtype.cls);
194 /* generate method profiling code */
196 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
197 /* count frequency */
199 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
200 M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
201 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
202 M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
204 /* PROFILE_CYCLE_START; */
207 /* create stack frame (if necessary) */
209 if (!jd->isleafmethod) {
211 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
214 if (cd->stackframesize)
215 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
217 /* save return address and used callee saved registers */
219 p = cd->stackframesize;
220 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
221 p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
223 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
224 p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
227 /* take arguments out of register or stack frame */
231 for (p = 0, l = 0; p < md->paramcount; p++) {
232 t = md->paramtypes[p].type;
233 var = &(rd->locals[l][t]);
235 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
239 s1 = md->params[p].regoff;
240 if (IS_INT_LNG_TYPE(t)) { /* integer args */
241 if (IS_2_WORD_TYPE(t))
242 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
243 rd->argintregs[GET_HIGH_REG(s1)]);
245 s2 = rd->argintregs[s1];
246 if (!md->params[p].inmemory) { /* register arguments */
247 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
248 if (IS_2_WORD_TYPE(t))
249 M_LNGMOVE(s2, var->regoff);
251 M_INTMOVE(s2, var->regoff);
253 } else { /* reg arg -> spilled */
254 if (IS_2_WORD_TYPE(t))
255 M_LST(s2, REG_SP, var->regoff * 4);
257 M_IST(s2, REG_SP, var->regoff * 4);
260 } else { /* stack arguments */
261 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
262 if (IS_2_WORD_TYPE(t))
263 M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
265 M_ILD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
267 } else { /* stack arg -> spilled */
269 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
270 M_IST(REG_ITMP1, REG_SP, var->regoff * 4);
271 if (IS_2_WORD_TYPE(t)) {
272 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
273 M_IST(REG_ITMP1, REG_SP, var->regoff * 4 + 4);
276 /* Reuse Memory Position on Caller Stack */
277 var->regoff = cd->stackframesize + s1;
282 } else { /* floating args */
283 if (!md->params[p].inmemory) { /* register arguments */
284 s2 = rd->argfltregs[s1];
285 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
286 M_FLTMOVE(s2, var->regoff);
288 } else { /* reg arg -> spilled */
289 if (IS_2_WORD_TYPE(t))
290 M_DST(s2, REG_SP, var->regoff * 4);
292 M_FST(s2, REG_SP, var->regoff * 4);
295 } else { /* stack arguments */
296 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
297 if (IS_2_WORD_TYPE(t))
298 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
301 M_FLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
303 } else { /* stack-arg -> spilled */
305 if (IS_2_WORD_TYPE(t)) {
306 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
307 M_DST(REG_FTMP1, REG_SP, var->regoff * 4);
308 var->regoff = cd->stackframesize + s1;
311 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
312 M_FST(REG_FTMP1, REG_SP, var->regoff * 4);
315 /* Reuse Memory Position on Caller Stack */
316 var->regoff = cd->stackframesize + s1;
323 #if defined(ENABLE_THREADS)
324 /* call monitorenter function */
326 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
327 /* stack offset for monitor argument */
331 # if !defined(NDEBUG)
332 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
333 M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
335 for (p = 0; p < INT_ARG_CNT; p++)
336 M_IST(rd->argintregs[p], REG_SP, LA_SIZE + p * 8);
338 for (p = 0; p < FLT_ARG_CNT; p++)
339 M_DST(rd->argfltregs[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
341 /* ATTENTION: We multiply here with 2, because we use * 8
342 above for simplicity and below * 4! */
344 s1 += (LA_SIZE_IN_POINTERS + ARG_CNT) * 2;
348 p = dseg_add_functionptr(cd, LOCK_monitor_enter);
349 M_ALD(REG_ITMP3, REG_PV, p);
352 /* get or test the lock object */
354 if (m->flags & ACC_STATIC) {
355 p = dseg_add_address(cd, &m->class->object.header);
356 M_ALD(rd->argintregs[0], REG_PV, p);
359 M_TST(rd->argintregs[0]);
361 codegen_add_nullpointerexception_ref(cd);
364 M_AST(rd->argintregs[0], REG_SP, s1 * 4);
367 # if !defined(NDEBUG)
368 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
369 for (p = 0; p < INT_ARG_CNT; p++)
370 M_ILD(rd->argintregs[p], REG_SP, LA_SIZE + p * 8);
372 for (p = 0; p < FLT_ARG_CNT; p++)
373 M_DLD(rd->argfltregs[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
375 M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
379 #endif /* defined(ENABLE_THREADS) */
381 /* call trace function */
383 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
384 emit_verbosecall_enter(jd);
387 /* end of header generation */
389 replacementpoint = code->rplpoints;
391 /* walk through all basic blocks */
393 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
395 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
397 if (bptr->flags >= BBREACHED) {
399 /* branch resolving */
403 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
404 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
410 /* handle replacement points */
412 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
413 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
418 /* generate basicblock profiling code */
420 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
421 /* count frequency */
423 disp = dseg_add_address(cd, code->bbfrequency);
424 M_ALD(REG_ITMP2, REG_PV, disp);
425 M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
426 M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
427 M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
429 /* if this is an exception handler, start profiling again */
431 /* if (bptr->type == BBTYPE_EXH) */
432 /* PROFILE_CYCLE_START; */
435 /* copy interface registers to their destination */
441 #if defined(ENABLE_LSRA)
443 while (src != NULL) {
445 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
446 /* d = reg_of_var(m, src, REG_ITMP1); */
447 if (!(src->flags & INMEMORY))
451 M_INTMOVE(REG_ITMP1, d);
452 emit_store(jd, NULL, src, d);
458 while (src != NULL) {
460 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
461 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
462 M_INTMOVE(REG_ITMP1, d);
463 emit_store(jd, NULL, src, d);
466 if (src->type == TYPE_LNG)
467 d = codegen_reg_of_var(rd, 0, src, REG_ITMP12_PACKED);
469 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
470 if ((src->varkind != STACKVAR)) {
472 if (IS_FLT_DBL_TYPE(s2)) {
473 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
474 s1 = rd->interfaces[len][s2].regoff;
478 if (IS_2_WORD_TYPE(s2)) {
480 rd->interfaces[len][s2].regoff * 4);
484 rd->interfaces[len][s2].regoff * 4);
487 emit_store(jd, NULL, src, d);
490 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
491 s1 = rd->interfaces[len][s2].regoff;
492 if (IS_2_WORD_TYPE(s2))
498 if (IS_2_WORD_TYPE(s2))
500 rd->interfaces[len][s2].regoff * 4);
503 rd->interfaces[len][s2].regoff * 4);
505 emit_store(jd, NULL, src, d);
512 #if defined(ENABLE_LSRA)
515 /* walk through all instructions */
521 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
522 if (iptr->line != currentline) {
523 dseg_addlinenumber(cd, iptr->line);
524 currentline = iptr->line;
527 MCODECHECK(64); /* an instruction usually needs < 64 words */
530 case ICMD_NOP: /* ... ==> ... */
531 case ICMD_INLINE_START:
532 case ICMD_INLINE_END:
535 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
537 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
540 codegen_add_nullpointerexception_ref(cd);
543 /* constant operations ************************************************/
545 case ICMD_ICONST: /* ... ==> ..., constant */
546 /* op1 = 0, val.i = constant */
548 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
549 ICONST(d, iptr->val.i);
550 emit_store(jd, iptr, iptr->dst, d);
553 case ICMD_LCONST: /* ... ==> ..., constant */
554 /* op1 = 0, val.l = constant */
556 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
557 LCONST(d, iptr->val.l);
558 emit_store(jd, iptr, iptr->dst, d);
561 case ICMD_FCONST: /* ... ==> ..., constant */
562 /* op1 = 0, val.f = constant */
564 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
565 a = dseg_add_float(cd, iptr->val.f);
567 emit_store(jd, iptr, iptr->dst, d);
570 case ICMD_DCONST: /* ... ==> ..., constant */
571 /* op1 = 0, val.d = constant */
573 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
574 a = dseg_add_double(cd, iptr->val.d);
576 emit_store(jd, iptr, iptr->dst, d);
579 case ICMD_ACONST: /* ... ==> ..., constant */
580 /* op1 = 0, val.a = constant */
582 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
584 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
585 constant_classref *cr = ICMD_ACONST_UNRESOLVED_CLASSREF(iptr);;
587 disp = dseg_add_unique_address(cd, cr);
589 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
592 if (opt_showdisassemble)
596 disp = dseg_add_address(cd, iptr->val.a);
598 M_ALD(d, REG_PV, disp);
599 emit_store(jd, iptr, iptr->dst, d);
603 /* load/store operations **********************************************/
605 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
606 case ICMD_ALOAD: /* op1 = local variable */
608 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
609 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
610 if ((iptr->dst->varkind == LOCALVAR) &&
611 (iptr->dst->varnum == iptr->op1))
613 if (var->flags & INMEMORY)
614 M_ILD(d, REG_SP, var->regoff * 4);
616 M_INTMOVE(var->regoff, d);
617 emit_store(jd, iptr, iptr->dst, d);
620 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
621 /* op1 = local variable */
623 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
624 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
625 if ((iptr->dst->varkind == LOCALVAR) &&
626 (iptr->dst->varnum == iptr->op1))
628 if (var->flags & INMEMORY)
629 M_LLD(d, REG_SP, var->regoff * 4);
631 M_LNGMOVE(var->regoff, d);
632 emit_store(jd, iptr, iptr->dst, d);
635 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
636 /* op1 = local variable */
638 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
639 if ((iptr->dst->varkind == LOCALVAR) &&
640 (iptr->dst->varnum == iptr->op1))
642 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
643 if (var->flags & INMEMORY)
644 M_FLD(d, REG_SP, var->regoff * 4);
646 M_FLTMOVE(var->regoff, d);
647 emit_store(jd, iptr, iptr->dst, d);
650 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
651 /* op1 = local variable */
653 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
654 if ((iptr->dst->varkind == LOCALVAR) &&
655 (iptr->dst->varnum == iptr->op1))
657 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
658 if (var->flags & INMEMORY)
659 M_DLD(d, REG_SP, var->regoff * 4);
661 M_FLTMOVE(var->regoff, d);
662 emit_store(jd, iptr, iptr->dst, d);
666 case ICMD_ISTORE: /* ..., value ==> ... */
667 case ICMD_ASTORE: /* op1 = local variable */
669 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
671 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
672 if (var->flags & INMEMORY) {
673 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
674 M_IST(s1, REG_SP, var->regoff * 4);
676 s1 = emit_load_s1(jd, iptr, src, var->regoff);
677 M_INTMOVE(s1, var->regoff);
681 case ICMD_LSTORE: /* ..., value ==> ... */
682 /* op1 = local variable */
684 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
686 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
687 if (var->flags & INMEMORY) {
688 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
689 M_LST(s1, REG_SP, var->regoff * 4);
691 s1 = emit_load_s1(jd, iptr, src, var->regoff);
692 M_LNGMOVE(s1, var->regoff);
696 case ICMD_FSTORE: /* ..., value ==> ... */
697 /* op1 = local variable */
699 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
701 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
702 if (var->flags & INMEMORY) {
703 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
704 M_FST(s1, REG_SP, var->regoff * 4);
706 s1 = emit_load_s1(jd, iptr, src, var->regoff);
707 M_FLTMOVE(s1, var->regoff);
711 case ICMD_DSTORE: /* ..., value ==> ... */
712 /* op1 = local variable */
714 if ((src->varkind == LOCALVAR) && (src->varnum == iptr->op1))
716 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
717 if (var->flags & INMEMORY) {
718 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
719 M_DST(s1, REG_SP, var->regoff * 4);
721 s1 = emit_load_s1(jd, iptr, src, var->regoff);
722 M_FLTMOVE(s1, var->regoff);
727 /* pop/dup/swap operations ********************************************/
729 /* attention: double and longs are only one entry in CACAO ICMDs */
731 case ICMD_POP: /* ..., value ==> ... */
732 case ICMD_POP2: /* ..., value, value ==> ... */
735 case ICMD_DUP: /* ..., a ==> ..., a, a */
736 M_COPY(src, iptr->dst);
739 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
741 M_COPY(src, iptr->dst);
742 M_COPY(src->prev, iptr->dst->prev);
743 M_COPY(iptr->dst, iptr->dst->prev->prev);
746 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
748 M_COPY(src, iptr->dst);
749 M_COPY(src->prev, iptr->dst->prev);
750 M_COPY(src->prev->prev, iptr->dst->prev->prev);
751 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
754 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
756 M_COPY(src, iptr->dst);
757 M_COPY(src->prev, iptr->dst->prev);
760 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
762 M_COPY(src, iptr->dst);
763 M_COPY(src->prev, iptr->dst->prev);
764 M_COPY(src->prev->prev, iptr->dst->prev->prev);
765 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
766 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
769 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
771 M_COPY(src, iptr->dst);
772 M_COPY(src->prev, iptr->dst->prev);
773 M_COPY(src->prev->prev, iptr->dst->prev->prev);
774 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
775 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
776 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
779 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
781 M_COPY(src, iptr->dst->prev);
782 M_COPY(src->prev, iptr->dst);
786 /* integer operations *************************************************/
788 case ICMD_INEG: /* ..., value ==> ..., - value */
790 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
791 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
793 emit_store(jd, iptr, iptr->dst, d);
796 case ICMD_LNEG: /* ..., value ==> ..., - value */
798 s1 = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
799 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
800 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
801 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
802 emit_store(jd, iptr, iptr->dst, d);
805 case ICMD_I2L: /* ..., value ==> ..., value */
807 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
808 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
809 M_INTMOVE(s1, GET_LOW_REG(d));
810 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
811 emit_store(jd, iptr, iptr->dst, d);
814 case ICMD_L2I: /* ..., value ==> ..., value */
816 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP2);
817 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
819 emit_store(jd, iptr, iptr->dst, d);
822 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
824 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
825 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
827 emit_store(jd, iptr, iptr->dst, d);
830 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
832 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
833 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
835 emit_store(jd, iptr, iptr->dst, d);
838 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
840 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
841 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
843 emit_store(jd, iptr, iptr->dst, d);
847 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
849 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
850 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
851 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
853 emit_store(jd, iptr, iptr->dst, d);
856 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
857 /* val.i = constant */
859 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
860 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
861 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
862 M_IADD_IMM(s1, iptr->val.i, d);
864 ICONST(REG_ITMP2, iptr->val.i);
865 M_IADD(s1, REG_ITMP2, d);
867 emit_store(jd, iptr, iptr->dst, d);
870 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
872 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
873 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
874 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
875 M_ADDC(s1, s2, GET_LOW_REG(d));
876 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
877 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
878 M_ADDE(s1, s2, GET_HIGH_REG(d));
879 emit_store(jd, iptr, iptr->dst, d);
882 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
883 /* val.l = constant */
885 s3 = iptr->val.l & 0xffffffff;
886 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
887 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
888 if ((s3 >= -32768) && (s3 <= 32767)) {
889 M_ADDIC(s1, s3, GET_LOW_REG(d));
891 ICONST(REG_ITMP2, s3);
892 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
894 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
895 s3 = iptr->val.l >> 32;
897 M_ADDME(s1, GET_HIGH_REG(d));
898 } else if (s3 == 0) {
899 M_ADDZE(s1, GET_HIGH_REG(d));
901 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
902 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
904 emit_store(jd, iptr, iptr->dst, d);
907 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
909 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
910 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
911 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
913 emit_store(jd, iptr, iptr->dst, d);
916 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
917 /* val.i = constant */
919 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
920 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
921 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
922 M_IADD_IMM(s1, -iptr->val.i, d);
924 ICONST(REG_ITMP2, -iptr->val.i);
925 M_IADD(s1, REG_ITMP2, d);
927 emit_store(jd, iptr, iptr->dst, d);
930 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
932 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
933 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
934 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
935 M_SUBC(s1, s2, GET_LOW_REG(d));
936 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
937 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
938 M_SUBE(s1, s2, GET_HIGH_REG(d));
939 emit_store(jd, iptr, iptr->dst, d);
942 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
943 /* val.l = constant */
945 s3 = (-iptr->val.l) & 0xffffffff;
946 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
947 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
948 if ((s3 >= -32768) && (s3 <= 32767)) {
949 M_ADDIC(s1, s3, GET_LOW_REG(d));
951 ICONST(REG_ITMP2, s3);
952 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
954 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
955 s3 = (-iptr->val.l) >> 32;
957 M_ADDME(s1, GET_HIGH_REG(d));
959 M_ADDZE(s1, GET_HIGH_REG(d));
961 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
962 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
964 emit_store(jd, iptr, iptr->dst, d);
967 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
969 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
970 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
971 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
974 codegen_add_arithmeticexception_ref(cd);
975 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
976 M_CMP(REG_ITMP3, s1);
977 M_BNE(3 + (s1 != d));
979 M_BNE(1 + (s1 != d));
983 emit_store(jd, iptr, iptr->dst, d);
986 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
988 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
989 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
990 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
993 codegen_add_arithmeticexception_ref(cd);
994 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
995 M_CMP(REG_ITMP3, s1);
1001 M_IDIV(s1, s2, REG_ITMP3);
1002 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
1003 M_ISUB(s1, REG_ITMP3, d);
1004 emit_store(jd, iptr, iptr->dst, d);
1007 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1008 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1013 s2 = emit_load_s2(jd, iptr, src, REG_ITMP12_PACKED);
1014 M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
1016 codegen_add_arithmeticexception_ref(cd);
1018 disp = dseg_add_functionptr(cd, bte->fp);
1019 M_ALD(REG_ITMP3, REG_PV, disp);
1022 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
1023 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
1026 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP12_PACKED);
1027 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
1028 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
1033 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
1034 M_LNGMOVE(REG_RESULT_PACKED, d);
1035 emit_store(jd, iptr, iptr->dst, d);
1038 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1040 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1041 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1042 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1044 emit_store(jd, iptr, iptr->dst, d);
1047 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1048 /* val.i = constant */
1050 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1051 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1052 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
1053 M_IMUL_IMM(s1, iptr->val.i, d);
1055 ICONST(REG_ITMP3, iptr->val.i);
1056 M_IMUL(s1, REG_ITMP3, d);
1058 emit_store(jd, iptr, iptr->dst, d);
1061 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1063 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1064 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1065 M_SRA_IMM(s1, iptr->val.i, d);
1067 emit_store(jd, iptr, iptr->dst, d);
1070 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1072 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1073 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1074 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1075 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1076 M_SLL(s1, REG_ITMP3, d);
1077 emit_store(jd, iptr, iptr->dst, d);
1080 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1081 /* val.i = constant */
1083 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1084 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1085 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
1086 emit_store(jd, iptr, iptr->dst, d);
1089 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1091 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1092 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1093 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1094 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1095 M_SRA(s1, REG_ITMP3, d);
1096 emit_store(jd, iptr, iptr->dst, d);
1099 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1100 /* val.i = constant */
1102 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1103 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1104 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
1105 emit_store(jd, iptr, iptr->dst, d);
1108 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1110 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1111 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1112 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1113 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1114 M_SRL(s1, REG_ITMP2, d);
1115 emit_store(jd, iptr, iptr->dst, d);
1118 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1119 /* val.i = constant */
1121 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1122 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1123 if (iptr->val.i & 0x1f) {
1124 M_SRL_IMM(s1, iptr->val.i & 0x1f, d);
1128 emit_store(jd, iptr, iptr->dst, d);
1131 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1133 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1134 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1135 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1137 emit_store(jd, iptr, iptr->dst, d);
1140 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1141 /* val.i = constant */
1143 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1144 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1145 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1146 M_AND_IMM(s1, iptr->val.i, d);
1149 else if (iptr->val.i == 0xffffff) {
1150 M_RLWINM(s1, 0, 8, 31, d);
1154 ICONST(REG_ITMP3, iptr->val.i);
1155 M_AND(s1, REG_ITMP3, d);
1157 emit_store(jd, iptr, iptr->dst, d);
1160 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1162 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1163 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1164 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1165 M_AND(s1, s2, GET_LOW_REG(d));
1166 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
1167 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
1168 M_AND(s1, s2, GET_HIGH_REG(d));
1169 emit_store(jd, iptr, iptr->dst, d);
1172 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1173 /* val.l = constant */
1175 s3 = iptr->val.l & 0xffffffff;
1176 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
1177 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1178 if ((s3 >= 0) && (s3 <= 65535)) {
1179 M_AND_IMM(s1, s3, GET_LOW_REG(d));
1181 ICONST(REG_ITMP3, s3);
1182 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
1184 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
1185 s3 = iptr->val.l >> 32;
1186 if ((s3 >= 0) && (s3 <= 65535)) {
1187 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
1189 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1190 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
1192 emit_store(jd, iptr, iptr->dst, d);
1195 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1196 /* val.i = constant */
1198 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1199 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1200 M_MOV(s1, REG_ITMP2);
1202 M_BGE(1 + 2*(iptr->val.i >= 32768));
1203 if (iptr->val.i >= 32768) {
1204 M_ADDIS(REG_ZERO, iptr->val.i >> 16, REG_ITMP2);
1205 M_OR_IMM(REG_ITMP2, iptr->val.i, REG_ITMP2);
1206 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1208 M_IADD_IMM(s1, iptr->val.i, REG_ITMP2);
1211 int b=0, m = iptr->val.i;
1214 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1216 M_ISUB(s1, REG_ITMP2, d);
1217 emit_store(jd, iptr, iptr->dst, d);
1220 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1222 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1223 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1224 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1226 emit_store(jd, iptr, iptr->dst, d);
1229 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1230 /* val.i = constant */
1232 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1233 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1234 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1235 M_OR_IMM(s1, iptr->val.i, d);
1237 ICONST(REG_ITMP3, iptr->val.i);
1238 M_OR(s1, REG_ITMP3, d);
1240 emit_store(jd, iptr, iptr->dst, d);
1243 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1245 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1246 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1247 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1248 M_OR(s1, s2, GET_LOW_REG(d));
1249 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
1250 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
1251 M_OR(s1, s2, GET_HIGH_REG(d));
1252 emit_store(jd, iptr, iptr->dst, d);
1255 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1256 /* val.l = constant */
1258 s3 = iptr->val.l & 0xffffffff;
1259 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
1260 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1261 if ((s3 >= 0) && (s3 <= 65535)) {
1262 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1264 ICONST(REG_ITMP3, s3);
1265 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1267 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
1268 s3 = iptr->val.l >> 32;
1269 if ((s3 >= 0) && (s3 <= 65535)) {
1270 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1272 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1273 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1275 emit_store(jd, iptr, iptr->dst, d);
1278 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1280 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1281 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1282 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1284 emit_store(jd, iptr, iptr->dst, d);
1287 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1288 /* val.i = constant */
1290 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1291 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1292 if ((iptr->val.i >= 0) && (iptr->val.i <= 65535)) {
1293 M_XOR_IMM(s1, iptr->val.i, d);
1295 ICONST(REG_ITMP3, iptr->val.i);
1296 M_XOR(s1, REG_ITMP3, d);
1298 emit_store(jd, iptr, iptr->dst, d);
1301 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1303 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
1304 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1305 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1306 M_XOR(s1, s2, GET_LOW_REG(d));
1307 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
1308 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP3); /* don't use REG_ITMP2 */
1309 M_XOR(s1, s2, GET_HIGH_REG(d));
1310 emit_store(jd, iptr, iptr->dst, d);
1313 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1314 /* val.l = constant */
1316 s3 = iptr->val.l & 0xffffffff;
1317 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
1318 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1319 if ((s3 >= 0) && (s3 <= 65535)) {
1320 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1322 ICONST(REG_ITMP3, s3);
1323 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1325 s1 = emit_load_s1_high(jd, iptr, src, REG_ITMP1);
1326 s3 = iptr->val.l >> 32;
1327 if ((s3 >= 0) && (s3 <= 65535)) {
1328 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1330 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1331 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1333 emit_store(jd, iptr, iptr->dst, d);
1336 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1337 /*******************************************************************
1338 TODO: CHANGE THIS TO A VERSION THAT WORKS !!!
1339 *******************************************************************/
1340 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP3);
1341 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
1342 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1344 int tempreg = false;
1348 if (src->prev->flags & INMEMORY) {
1349 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1351 tempreg = tempreg || (d == GET_HIGH_REG(src->prev->regoff))
1352 || (d == GET_LOW_REG(src->prev->regoff));
1354 if (src->flags & INMEMORY) {
1355 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1357 tempreg = tempreg || (d == GET_HIGH_REG(src->regoff))
1358 || (d == GET_LOW_REG(src->regoff));
1361 dreg = tempreg ? REG_ITMP1 : d;
1362 M_IADD_IMM(REG_ZERO, 1, dreg);
1367 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP3);
1368 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
1372 M_IADD_IMM(dreg, -1, dreg);
1373 M_IADD_IMM(dreg, -1, dreg);
1374 gen_resolvebranch(br1, br1, cd->mcodeptr);
1375 gen_resolvebranch(br1 + 1 * 4, br1 + 1 * 4, cd->mcodeptr - 2 * 4);
1378 emit_store(jd, iptr, iptr->dst, d);
1381 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1382 /* op1 = variable, val.i = constant */
1384 var = &(rd->locals[iptr->op1][TYPE_INT]);
1385 if (var->flags & INMEMORY) {
1387 M_ILD(s1, REG_SP, var->regoff * 4);
1395 M_ADDIS(s1, m >> 16, s1);
1397 M_IADD_IMM(s1, m & 0xffff, s1);
1399 if (var->flags & INMEMORY)
1400 M_IST(s1, REG_SP, var->regoff * 4);
1404 /* floating operations ************************************************/
1406 case ICMD_FNEG: /* ..., value ==> ..., - value */
1408 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1409 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1411 emit_store(jd, iptr, iptr->dst, d);
1414 case ICMD_DNEG: /* ..., value ==> ..., - value */
1416 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1417 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1419 emit_store(jd, iptr, iptr->dst, d);
1422 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1424 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1425 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1426 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1428 emit_store(jd, iptr, iptr->dst, d);
1431 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1433 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1434 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1435 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1437 emit_store(jd, iptr, iptr->dst, d);
1440 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1442 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1443 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1444 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1446 emit_store(jd, iptr, iptr->dst, d);
1449 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1451 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1452 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1453 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1455 emit_store(jd, iptr, iptr->dst, d);
1458 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1460 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1461 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1462 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1464 emit_store(jd, iptr, iptr->dst, d);
1467 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1469 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1470 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1471 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1473 emit_store(jd, iptr, iptr->dst, d);
1476 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1478 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1479 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1480 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1482 emit_store(jd, iptr, iptr->dst, d);
1485 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1487 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1488 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1489 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1491 emit_store(jd, iptr, iptr->dst, d);
1494 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1497 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1498 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1500 disp = dseg_add_float(cd, 0.0);
1501 M_FLD(REG_FTMP2, REG_PV, disp);
1502 M_FCMPU(s1, REG_FTMP2);
1504 disp = dseg_add_unique_s4(cd, 0);
1505 M_CVTDL_C(s1, REG_FTMP1);
1506 M_LDA(REG_ITMP1, REG_PV, disp);
1507 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1508 M_ILD(d, REG_PV, disp);
1509 emit_store(jd, iptr, iptr->dst, d);
1512 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1514 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1515 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1517 emit_store(jd, iptr, iptr->dst, d);
1520 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1522 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1523 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1525 emit_store(jd, iptr, iptr->dst, d);
1528 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1529 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1532 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1533 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1534 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1536 M_IADD_IMM(REG_ZERO, -1, d);
1539 M_IADD_IMM(REG_ZERO, 0, d);
1541 M_IADD_IMM(REG_ZERO, 1, d);
1542 emit_store(jd, iptr, iptr->dst, d);
1545 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1546 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1548 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1549 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1550 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1552 M_IADD_IMM(REG_ZERO, 1, d);
1555 M_IADD_IMM(REG_ZERO, 0, d);
1557 M_IADD_IMM(REG_ZERO, -1, d);
1558 emit_store(jd, iptr, iptr->dst, d);
1561 case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */
1562 case ICMD_IF_DCMPEQ:
1564 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1565 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1569 codegen_addreference(cd, (basicblock *) iptr->target);
1572 case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */
1573 case ICMD_IF_DCMPNE:
1575 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1576 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1579 codegen_addreference(cd, (basicblock *) iptr->target);
1581 codegen_addreference(cd, (basicblock *) iptr->target);
1585 case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */
1586 case ICMD_IF_DCMPL_LT:
1588 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1589 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1592 codegen_addreference(cd, (basicblock *) iptr->target);
1594 codegen_addreference(cd, (basicblock *) iptr->target);
1597 case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */
1598 case ICMD_IF_DCMPL_GT:
1600 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1601 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1605 codegen_addreference(cd, (basicblock *) iptr->target);
1608 case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */
1609 case ICMD_IF_DCMPL_LE:
1611 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1612 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1615 codegen_addreference(cd, (basicblock *) iptr->target);
1617 codegen_addreference(cd, (basicblock *) iptr->target);
1620 case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */
1621 case ICMD_IF_DCMPL_GE:
1623 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1624 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1628 codegen_addreference(cd, (basicblock *) iptr->target);
1631 case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */
1632 case ICMD_IF_DCMPG_LT:
1634 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1635 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1639 codegen_addreference(cd, (basicblock *) iptr->target);
1642 case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */
1643 case ICMD_IF_DCMPG_GT:
1645 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1646 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1649 codegen_addreference(cd, (basicblock *) iptr->target);
1651 codegen_addreference(cd, (basicblock *) iptr->target);
1654 case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */
1655 case ICMD_IF_DCMPG_LE:
1657 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1658 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1662 codegen_addreference(cd, (basicblock *) iptr->target);
1665 case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */
1666 case ICMD_IF_DCMPG_GE:
1668 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1669 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1672 codegen_addreference(cd, (basicblock *) iptr->target);
1674 codegen_addreference(cd, (basicblock *) iptr->target);
1678 /* memory operations **************************************************/
1680 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1682 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1683 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1684 gen_nullptr_check(s1);
1685 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1686 emit_store(jd, iptr, iptr->dst, d);
1689 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1691 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1692 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1693 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1694 if (iptr->op1 == 0) {
1695 gen_nullptr_check(s1);
1698 M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1699 M_LBZX(d, s1, REG_ITMP2);
1701 emit_store(jd, iptr, iptr->dst, d);
1704 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1706 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1707 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1708 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1709 if (iptr->op1 == 0) {
1710 gen_nullptr_check(s1);
1713 M_SLL_IMM(s2, 1, REG_ITMP2);
1714 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1715 M_LHZX(d, s1, REG_ITMP2);
1716 emit_store(jd, iptr, iptr->dst, d);
1719 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1721 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1722 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1723 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1724 if (iptr->op1 == 0) {
1725 gen_nullptr_check(s1);
1728 M_SLL_IMM(s2, 1, REG_ITMP2);
1729 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1730 M_LHAX(d, s1, REG_ITMP2);
1731 emit_store(jd, iptr, iptr->dst, d);
1734 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1736 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1737 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1738 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1739 if (iptr->op1 == 0) {
1740 gen_nullptr_check(s1);
1743 M_SLL_IMM(s2, 2, REG_ITMP2);
1744 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1745 M_LWZX(d, s1, REG_ITMP2);
1746 emit_store(jd, iptr, iptr->dst, d);
1749 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1751 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1752 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1753 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1754 if (iptr->op1 == 0) {
1755 gen_nullptr_check(s1);
1758 M_SLL_IMM(s2, 3, REG_ITMP2);
1759 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1760 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1761 emit_store(jd, iptr, iptr->dst, d);
1764 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1766 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1767 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1768 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1769 if (iptr->op1 == 0) {
1770 gen_nullptr_check(s1);
1773 M_SLL_IMM(s2, 2, REG_ITMP2);
1774 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1775 M_LFSX(d, s1, REG_ITMP2);
1776 emit_store(jd, iptr, iptr->dst, d);
1779 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1781 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1782 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1783 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1784 if (iptr->op1 == 0) {
1785 gen_nullptr_check(s1);
1788 M_SLL_IMM(s2, 3, REG_ITMP2);
1789 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1790 M_LFDX(d, s1, REG_ITMP2);
1791 emit_store(jd, iptr, iptr->dst, d);
1794 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1796 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1797 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1798 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1799 if (iptr->op1 == 0) {
1800 gen_nullptr_check(s1);
1803 M_SLL_IMM(s2, 2, REG_ITMP2);
1804 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1805 M_LWZX(d, s1, REG_ITMP2);
1806 emit_store(jd, iptr, iptr->dst, d);
1810 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1812 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1813 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1814 if (iptr->op1 == 0) {
1815 gen_nullptr_check(s1);
1818 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1819 M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1820 M_STBX(s3, s1, REG_ITMP2);
1823 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1825 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1826 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1827 if (iptr->op1 == 0) {
1828 gen_nullptr_check(s1);
1831 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1832 M_SLL_IMM(s2, 1, REG_ITMP2);
1833 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1834 M_STHX(s3, s1, REG_ITMP2);
1837 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1839 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1840 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1841 if (iptr->op1 == 0) {
1842 gen_nullptr_check(s1);
1845 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1846 M_SLL_IMM(s2, 1, REG_ITMP2);
1847 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1848 M_STHX(s3, s1, REG_ITMP2);
1851 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1853 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1854 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1855 if (iptr->op1 == 0) {
1856 gen_nullptr_check(s1);
1859 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1860 M_SLL_IMM(s2, 2, REG_ITMP2);
1861 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1862 M_STWX(s3, s1, REG_ITMP2);
1865 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1867 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1868 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1869 if (iptr->op1 == 0) {
1870 gen_nullptr_check(s1);
1873 s3 = emit_load_s3_high(jd, iptr, src, REG_ITMP3);
1874 M_SLL_IMM(s2, 3, REG_ITMP2);
1875 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
1876 M_STWX(s3, s1, REG_ITMP2);
1877 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1878 s3 = emit_load_s3_low(jd, iptr, src, REG_ITMP3);
1879 M_STWX(s3, s1, REG_ITMP2);
1882 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1884 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1885 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1886 if (iptr->op1 == 0) {
1887 gen_nullptr_check(s1);
1890 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1891 M_SLL_IMM(s2, 2, REG_ITMP2);
1892 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1893 M_STFSX(s3, s1, REG_ITMP2);
1896 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1898 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1899 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1900 if (iptr->op1 == 0) {
1901 gen_nullptr_check(s1);
1904 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1905 M_SLL_IMM(s2, 3, REG_ITMP2);
1906 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1907 M_STFDX(s3, s1, REG_ITMP2);
1910 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1912 s1 = emit_load_s1(jd, iptr, src->prev->prev, rd->argintregs[0]);
1913 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1914 if (iptr->op1 == 0) {
1915 gen_nullptr_check(s1);
1918 s3 = emit_load_s3(jd, iptr, src, rd->argintregs[1]);
1920 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1921 M_ALD(REG_ITMP3, REG_PV, disp);
1924 M_INTMOVE(s1, rd->argintregs[0]);
1925 M_INTMOVE(s3, rd->argintregs[1]);
1930 codegen_add_arraystoreexception_ref(cd);
1932 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1933 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1934 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1935 M_SLL_IMM(s2, 2, REG_ITMP2);
1936 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1937 M_STWX(s3, s1, REG_ITMP2);
1941 case ICMD_GETSTATIC: /* ... ==> ..., value */
1942 /* op1 = type, val.a = field address */
1944 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1945 unresolved_field *uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
1947 disp = dseg_add_unique_address(cd, uf);
1949 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1951 if (opt_showdisassemble)
1955 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1957 disp = dseg_add_address(cd, &(fi->value));
1959 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1960 codegen_addpatchref(cd, PATCHER_initialize_class,
1963 if (opt_showdisassemble)
1968 M_ALD(REG_ITMP1, REG_PV, disp);
1969 switch (iptr->op1) {
1971 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1972 M_ILD_INTERN(d, REG_ITMP1, 0);
1975 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
1976 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1977 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1980 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1981 M_ALD_INTERN(d, REG_ITMP1, 0);
1984 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1985 M_FLD_INTERN(d, REG_ITMP1, 0);
1988 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1989 M_DLD_INTERN(d, REG_ITMP1, 0);
1992 emit_store(jd, iptr, iptr->dst, d);
1995 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1996 /* op1 = type, val.a = field address */
1998 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1999 unresolved_field *uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
2001 disp = dseg_add_unique_address(cd, uf);
2003 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2005 if (opt_showdisassemble)
2009 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2011 disp = dseg_add_address(cd, &(fi->value));
2013 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2014 codegen_addpatchref(cd, PATCHER_initialize_class,
2017 if (opt_showdisassemble)
2022 M_ALD(REG_ITMP1, REG_PV, disp);
2023 switch (iptr->op1) {
2025 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
2026 M_IST_INTERN(s1, REG_ITMP1, 0);
2029 s1 = emit_load_s1(jd, iptr, src, REG_ITMP23_PACKED);
2030 M_LST_INTERN(s1, REG_ITMP1, 0);
2033 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
2034 M_AST_INTERN(s1, REG_ITMP1, 0);
2037 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2038 M_FST_INTERN(s1, REG_ITMP1, 0);
2041 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
2042 M_DST_INTERN(s1, REG_ITMP1, 0);
2048 case ICMD_GETFIELD: /* ... ==> ..., value */
2049 /* op1 = type, val.i = field offset */
2051 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2052 gen_nullptr_check(s1);
2054 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2055 unresolved_field *uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
2057 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2059 if (opt_showdisassemble)
2065 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2069 switch (iptr->op1) {
2071 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2075 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP12_PACKED);
2076 if (GET_HIGH_REG(d) == s1) {
2077 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2078 M_ILD(GET_HIGH_REG(d), s1, disp);
2081 M_ILD(GET_HIGH_REG(d), s1, disp);
2082 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2086 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2090 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2094 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2098 emit_store(jd, iptr, iptr->dst, d);
2101 case ICMD_PUTFIELD: /* ..., value ==> ... */
2102 /* op1 = type, val.i = field offset */
2104 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2105 gen_nullptr_check(s1);
2107 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2108 if (IS_2_WORD_TYPE(iptr->op1))
2109 s2 = emit_load_s2(jd, iptr, src, REG_ITMP23_PACKED);
2111 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2114 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2116 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2117 unresolved_field *uf = INSTRUCTION_UNRESOLVED_FIELD(iptr);
2119 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2121 if (opt_showdisassemble)
2127 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2131 switch (iptr->op1) {
2133 M_IST(s2, s1, disp);
2136 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
2137 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
2140 M_AST(s2, s1, disp);
2143 M_FST(s2, s1, disp);
2146 M_DST(s2, s1, disp);
2152 /* branch operations **************************************************/
2154 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2156 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2157 M_INTMOVE(s1, REG_ITMP1_XPTR);
2159 #ifdef ENABLE_VERIFIER
2161 unresolved_class *uc = INSTRUCTION_UNRESOLVED_CLASS(iptr);
2163 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2165 if (opt_showdisassemble)
2168 #endif /* ENABLE_VERIFIER */
2170 disp = dseg_add_functionptr(cd, asm_handle_exception);
2171 M_ALD(REG_ITMP2, REG_PV, disp);
2174 if (jd->isleafmethod)
2175 M_MFLR(REG_ITMP3); /* save LR */
2177 M_BL(0); /* get current PC */
2178 M_MFLR(REG_ITMP2_XPC);
2180 if (jd->isleafmethod)
2181 M_MTLR(REG_ITMP3); /* restore LR */
2183 M_RTS; /* jump to CTR */
2187 case ICMD_GOTO: /* ... ==> ... */
2188 /* op1 = target JavaVM pc */
2190 codegen_addreference(cd, (basicblock *) iptr->target);
2194 case ICMD_JSR: /* ... ==> ... */
2195 /* op1 = target JavaVM pc */
2197 if (jd->isleafmethod)
2202 M_IADD_IMM(REG_ITMP1, jd->isleafmethod ? 4*4 : 3*4, REG_ITMP1);
2204 if (jd->isleafmethod)
2208 codegen_addreference(cd, (basicblock *) iptr->target);
2211 case ICMD_RET: /* ... ==> ... */
2212 /* op1 = local variable */
2214 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2215 if (var->flags & INMEMORY) {
2216 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2219 M_MTCTR(var->regoff);
2225 case ICMD_IFNULL: /* ..., value ==> ... */
2226 /* op1 = target JavaVM pc */
2228 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2231 codegen_addreference(cd, (basicblock *) iptr->target);
2234 case ICMD_IFNONNULL: /* ..., value ==> ... */
2235 /* op1 = target JavaVM pc */
2237 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2240 codegen_addreference(cd, (basicblock *) iptr->target);
2248 case ICMD_IFEQ: /* ..., value ==> ... */
2249 /* op1 = target JavaVM pc, val.i = constant */
2251 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2252 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767))
2253 M_CMPI(s1, iptr->val.i);
2255 ICONST(REG_ITMP2, iptr->val.i);
2256 M_CMP(s1, REG_ITMP2);
2258 switch (iptr->opc) {
2278 codegen_addreference(cd, (basicblock *) iptr->target);
2282 case ICMD_IF_LEQ: /* ..., value ==> ... */
2283 /* op1 = target JavaVM pc, val.l = constant */
2285 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2286 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2287 if (iptr->val.l == 0) {
2288 M_OR_TST(s1, s2, REG_ITMP3);
2289 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2290 M_XOR_IMM(s2, 0, REG_ITMP2);
2291 M_XOR_IMM(s1, iptr->val.l & 0xffff, REG_ITMP1);
2292 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2294 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2295 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2296 ICONST(REG_ITMP3, iptr->val.l >> 32);
2297 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2298 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2301 codegen_addreference(cd, (basicblock *) iptr->target);
2304 case ICMD_IF_LLT: /* ..., value ==> ... */
2305 /* op1 = target JavaVM pc, val.l = constant */
2306 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2307 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2308 if (iptr->val.l == 0) {
2309 /* if high word is less than zero, the whole long is too */
2311 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2314 codegen_addreference(cd, (basicblock *) iptr->target);
2316 M_CMPUI(s1, iptr->val.l & 0xffff);
2318 ICONST(REG_ITMP3, iptr->val.l >> 32);
2319 M_CMP(s2, REG_ITMP3);
2321 codegen_addreference(cd, (basicblock *) iptr->target);
2323 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2324 M_CMPU(s1, REG_ITMP3);
2327 codegen_addreference(cd, (basicblock *) iptr->target);
2330 case ICMD_IF_LLE: /* ..., value ==> ... */
2331 /* op1 = target JavaVM pc, val.l = constant */
2333 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2334 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2335 /* if (iptr->val.l == 0) { */
2336 /* M_OR(s1, s2, REG_ITMP3); */
2337 /* M_CMPI(REG_ITMP3, 0); */
2340 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2343 codegen_addreference(cd, (basicblock *) iptr->target);
2345 M_CMPUI(s1, iptr->val.l & 0xffff);
2347 ICONST(REG_ITMP3, iptr->val.l >> 32);
2348 M_CMP(s2, REG_ITMP3);
2350 codegen_addreference(cd, (basicblock *) iptr->target);
2352 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2353 M_CMPU(s1, REG_ITMP3);
2356 codegen_addreference(cd, (basicblock *) iptr->target);
2359 case ICMD_IF_LNE: /* ..., value ==> ... */
2360 /* op1 = target JavaVM pc, val.l = constant */
2362 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2363 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2364 if (iptr->val.l == 0) {
2365 M_OR_TST(s1, s2, REG_ITMP3);
2366 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2367 M_XOR_IMM(s2, 0, REG_ITMP2);
2368 M_XOR_IMM(s1, iptr->val.l & 0xffff, REG_ITMP1);
2369 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2371 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2372 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2373 ICONST(REG_ITMP3, iptr->val.l >> 32);
2374 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2375 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2378 codegen_addreference(cd, (basicblock *) iptr->target);
2381 case ICMD_IF_LGT: /* ..., value ==> ... */
2382 /* op1 = target JavaVM pc, val.l = constant */
2384 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2385 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2386 /* if (iptr->val.l == 0) { */
2387 /* M_OR(s1, s2, REG_ITMP3); */
2388 /* M_CMPI(REG_ITMP3, 0); */
2391 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2394 codegen_addreference(cd, (basicblock *) iptr->target);
2396 M_CMPUI(s1, iptr->val.l & 0xffff);
2398 ICONST(REG_ITMP3, iptr->val.l >> 32);
2399 M_CMP(s2, REG_ITMP3);
2401 codegen_addreference(cd, (basicblock *) iptr->target);
2403 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2404 M_CMPU(s1, REG_ITMP3);
2407 codegen_addreference(cd, (basicblock *) iptr->target);
2410 case ICMD_IF_LGE: /* ..., value ==> ... */
2411 /* op1 = target JavaVM pc, val.l = constant */
2413 s1 = emit_load_s1_low(jd, iptr, src, REG_ITMP1);
2414 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2415 if (iptr->val.l == 0) {
2416 /* if high word is greater equal zero, the whole long is too */
2418 } else if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
2421 codegen_addreference(cd, (basicblock *) iptr->target);
2423 M_CMPUI(s1, iptr->val.l & 0xffff);
2425 ICONST(REG_ITMP3, iptr->val.l >> 32);
2426 M_CMP(s2, REG_ITMP3);
2428 codegen_addreference(cd, (basicblock *) iptr->target);
2430 ICONST(REG_ITMP3, iptr->val.l & 0xffffffff);
2431 M_CMPU(s1, REG_ITMP3);
2434 codegen_addreference(cd, (basicblock *) iptr->target);
2437 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2438 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2440 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2441 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2444 codegen_addreference(cd, (basicblock *) iptr->target);
2447 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2448 /* op1 = target JavaVM pc */
2450 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2451 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2453 /* load low-bits before the branch, so we know the distance */
2454 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2455 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2459 codegen_addreference(cd, (basicblock *) iptr->target);
2462 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2463 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2465 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2466 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2469 codegen_addreference(cd, (basicblock *) iptr->target);
2472 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2473 /* op1 = target JavaVM pc */
2475 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2476 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2479 codegen_addreference(cd, (basicblock *) iptr->target);
2480 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2481 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2484 codegen_addreference(cd, (basicblock *) iptr->target);
2487 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2488 /* op1 = target JavaVM pc */
2490 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2491 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2494 codegen_addreference(cd, (basicblock *) iptr->target);
2497 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2498 /* op1 = target JavaVM pc */
2500 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2501 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2504 codegen_addreference(cd, (basicblock *) iptr->target);
2505 /* load low-bits before the branch, so we know the distance */
2506 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2507 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2511 codegen_addreference(cd, (basicblock *) iptr->target);
2514 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2515 /* op1 = target JavaVM pc */
2517 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2518 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2521 codegen_addreference(cd, (basicblock *) iptr->target);
2524 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2525 /* op1 = target JavaVM pc */
2527 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2528 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2531 codegen_addreference(cd, (basicblock *) iptr->target);
2532 /* load low-bits before the branch, so we know the distance */
2533 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2534 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2538 codegen_addreference(cd, (basicblock *) iptr->target);
2541 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2542 /* op1 = target JavaVM pc */
2544 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2545 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2548 codegen_addreference(cd, (basicblock *) iptr->target);
2551 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2552 /* op1 = target JavaVM pc */
2554 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2555 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2558 codegen_addreference(cd, (basicblock *) iptr->target);
2559 /* load low-bits before the branch, so we know the distance */
2560 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2561 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2565 codegen_addreference(cd, (basicblock *) iptr->target);
2568 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2569 /* op1 = target JavaVM pc */
2571 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2572 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2575 codegen_addreference(cd, (basicblock *) iptr->target);
2578 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2579 /* op1 = target JavaVM pc */
2581 s1 = emit_load_s1_high(jd, iptr, src->prev, REG_ITMP1);
2582 s2 = emit_load_s2_high(jd, iptr, src, REG_ITMP2);
2585 codegen_addreference(cd, (basicblock *) iptr->target);
2586 /* load low-bits before the branch, so we know the distance */
2587 s1 = emit_load_s1_low(jd, iptr, src->prev, REG_ITMP1);
2588 s2 = emit_load_s2_low(jd, iptr, src, REG_ITMP2);
2592 codegen_addreference(cd, (basicblock *) iptr->target);
2595 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2597 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2598 M_INTMOVE(s1, REG_RESULT);
2599 goto nowperformreturn;
2601 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2603 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2604 M_INTMOVE(s1, REG_RESULT);
2606 #ifdef ENABLE_VERIFIER
2608 unresolved_class *uc = INSTRUCTION_UNRESOLVED_CLASS(iptr);
2610 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2612 if (opt_showdisassemble)
2615 #endif /* ENABLE_VERIFIER */
2616 goto nowperformreturn;
2618 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2620 s1 = emit_load_s1(jd, iptr, src, REG_RESULT_PACKED);
2621 M_LNGMOVE(s1, REG_RESULT_PACKED);
2622 goto nowperformreturn;
2624 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2627 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2628 M_FLTMOVE(s1, REG_FRESULT);
2629 goto nowperformreturn;
2631 case ICMD_RETURN: /* ... ==> ... */
2637 p = cd->stackframesize;
2639 /* call trace function */
2641 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2642 emit_verbosecall_exit(jd);
2644 #if defined(ENABLE_THREADS)
2645 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2646 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2647 M_ALD(REG_ITMP3, REG_PV, disp);
2650 /* we need to save the proper return value */
2652 switch (iptr->opc) {
2654 M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2658 M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2661 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2664 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2668 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 4);
2671 /* and now restore the proper return value */
2673 switch (iptr->opc) {
2675 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2679 M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2682 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2685 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2691 /* restore return address */
2693 if (!jd->isleafmethod) {
2694 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2695 may have a displacement overflow. */
2697 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
2701 /* restore saved registers */
2703 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2704 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2706 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2707 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2710 /* deallocate stack */
2712 if (cd->stackframesize)
2713 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4);
2721 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2726 tptr = (void **) iptr->target;
2728 s4ptr = iptr->val.a;
2729 l = s4ptr[1]; /* low */
2730 i = s4ptr[2]; /* high */
2732 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2734 M_INTMOVE(s1, REG_ITMP1);
2735 } else if (l <= 32768) {
2736 M_LDA(REG_ITMP1, s1, -l);
2738 ICONST(REG_ITMP2, l);
2739 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2745 M_CMPUI(REG_ITMP1, i - 1);
2747 codegen_addreference(cd, (basicblock *) tptr[0]);
2749 /* build jump table top down and use address of lowest entry */
2751 /* s4ptr += 3 + i; */
2755 dseg_add_target(cd, (basicblock *) tptr[0]);
2760 /* length of dataseg after last dseg_add_target is used by load */
2762 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2763 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2764 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2771 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2773 s4 i, l, val, *s4ptr;
2776 tptr = (void **) iptr->target;
2778 s4ptr = iptr->val.a;
2779 l = s4ptr[0]; /* default */
2780 i = s4ptr[1]; /* count */
2782 MCODECHECK((i<<2)+8);
2783 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2789 if ((val >= -32768) && (val <= 32767)) {
2793 a = dseg_add_s4(cd, val);
2794 M_ILD(REG_ITMP2, REG_PV, a);
2795 M_CMP(s1, REG_ITMP2);
2798 codegen_addreference(cd, (basicblock *) tptr[0]);
2802 tptr = (void **) iptr->target;
2803 codegen_addreference(cd, (basicblock *) tptr[0]);
2810 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2811 /* op1 = arg count val.a = builtintable entry */
2817 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2818 /* op1 = arg count, val.a = method pointer */
2820 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2821 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2822 case ICMD_INVOKEINTERFACE:
2824 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2825 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
2829 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
2830 md = lm->parseddesc;
2834 s3 = md->paramcount;
2836 MCODECHECK((s3 << 1) + 64);
2838 /* copy arguments to registers or stack location */
2840 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2841 if (src->varkind == ARGVAR)
2843 if (IS_INT_LNG_TYPE(src->type)) {
2844 if (!md->params[s3].inmemory) {
2845 if (IS_2_WORD_TYPE(src->type)) {
2847 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
2848 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]);
2849 d = emit_load_s1(jd, iptr, src, s1);
2853 s1 = rd->argintregs[md->params[s3].regoff];
2854 d = emit_load_s1(jd, iptr, src, s1);
2859 if (IS_2_WORD_TYPE(src->type)) {
2860 d = emit_load_s1(jd, iptr, src, REG_ITMP12_PACKED);
2861 M_LST(d, REG_SP, md->params[s3].regoff * 4);
2864 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
2865 M_IST(d, REG_SP, md->params[s3].regoff * 4);
2870 if (!md->params[s3].inmemory) {
2871 s1 = rd->argfltregs[md->params[s3].regoff];
2872 d = emit_load_s1(jd, iptr, src, s1);
2876 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
2877 if (IS_2_WORD_TYPE(src->type))
2878 M_DST(d, REG_SP, md->params[s3].regoff * 4);
2880 M_FST(d, REG_SP, md->params[s3].regoff * 4);
2885 switch (iptr->opc) {
2887 disp = dseg_add_functionptr(cd, bte->fp);
2888 d = md->returntype.type;
2890 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
2893 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2895 M_LDA(REG_PV, REG_ITMP1, -disp);
2897 /* if op1 == true, we need to check for an exception */
2899 if (iptr->op1 == true) {
2900 M_CMPI(REG_RESULT, 0);
2902 codegen_add_fillinstacktrace_ref(cd);
2906 case ICMD_INVOKESPECIAL:
2907 gen_nullptr_check(rd->argintregs[0]);
2908 M_ILD(REG_ITMP1, rd->argintregs[0], 0); /* hardware nullptr */
2911 case ICMD_INVOKESTATIC:
2913 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2915 disp = dseg_add_unique_address(cd, um);
2917 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2920 if (opt_showdisassemble)
2923 d = md->returntype.type;
2926 disp = dseg_add_address(cd, lm->stubroutine);
2927 d = md->returntype.type;
2930 M_ALD(REG_PV, REG_PV, disp);
2933 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2935 M_LDA(REG_PV, REG_ITMP1, -disp);
2938 case ICMD_INVOKEVIRTUAL:
2939 gen_nullptr_check(rd->argintregs[0]);
2942 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2944 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2946 if (opt_showdisassemble)
2950 d = md->returntype.type;
2953 s1 = OFFSET(vftbl_t, table[0]) +
2954 sizeof(methodptr) * lm->vftblindex;
2955 d = md->returntype.type;
2958 M_ALD(REG_METHODPTR, rd->argintregs[0],
2959 OFFSET(java_objectheader, vftbl));
2960 M_ALD(REG_PV, REG_METHODPTR, s1);
2963 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2965 M_LDA(REG_PV, REG_ITMP1, -disp);
2968 case ICMD_INVOKEINTERFACE:
2969 gen_nullptr_check(rd->argintregs[0]);
2972 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2974 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2976 if (opt_showdisassemble)
2981 d = md->returntype.type;
2984 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2985 sizeof(methodptr*) * lm->class->index;
2987 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2989 d = md->returntype.type;
2992 M_ALD(REG_METHODPTR, rd->argintregs[0],
2993 OFFSET(java_objectheader, vftbl));
2994 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2995 M_ALD(REG_PV, REG_METHODPTR, s2);
2998 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3000 M_LDA(REG_PV, REG_ITMP1, -disp);
3004 /* d contains return type */
3006 if (d != TYPE_VOID) {
3007 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3008 if (IS_2_WORD_TYPE(iptr->dst->type)) {
3009 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_PACKED);
3010 M_LNGMOVE(REG_RESULT_PACKED, s1);
3013 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3014 M_INTMOVE(REG_RESULT, s1);
3018 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3019 M_FLTMOVE(REG_FRESULT, s1);
3021 emit_store(jd, iptr, iptr->dst, s1);
3026 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3027 /* op1: 0 == array, 1 == class */
3028 /* val.a: (classinfo*) superclass */
3030 /* superclass is an interface:
3032 * OK if ((sub == NULL) ||
3033 * (sub->vftbl->interfacetablelength > super->index) &&
3034 * (sub->vftbl->interfacetable[-super->index] != NULL));
3036 * superclass is a class:
3038 * OK if ((sub == NULL) || (0
3039 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3040 * super->vftbl->diffvall));
3043 if (iptr->op1 == 1) {
3044 /* object type cast-check */
3049 super = (classinfo *) iptr->val.a;
3054 superindex = super->index;
3056 #if defined(ENABLE_THREADS)
3057 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3059 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3061 /* calculate interface checkcast code size */
3065 s2 += (opt_showdisassemble ? 1 : 0);
3067 /* calculate class checkcast code size */
3069 s3 = 8 + (s1 == REG_ITMP1);
3071 s3 += (opt_showdisassemble ? 1 : 0);
3073 /* if class is not resolved, check which code to call */
3075 if (super == NULL) {
3077 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3079 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3081 codegen_addpatchref(cd,
3082 PATCHER_resolve_classref_to_flags,
3083 (constant_classref *) iptr->target,
3086 if (opt_showdisassemble)
3089 M_ILD(REG_ITMP2, REG_PV, disp);
3090 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3094 /* interface checkcast code */
3096 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3097 if (super == NULL) {
3098 codegen_addpatchref(cd,
3099 PATCHER_checkcast_instanceof_interface,
3100 (constant_classref *) iptr->target,
3103 if (opt_showdisassemble)
3111 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3112 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3113 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3115 codegen_add_classcastexception_ref(cd, s1);
3116 M_ALD(REG_ITMP3, REG_ITMP2,
3117 OFFSET(vftbl_t, interfacetable[0]) -
3118 superindex * sizeof(methodptr*));
3121 codegen_add_classcastexception_ref(cd, s1);
3127 /* class checkcast code */
3129 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3130 if (super == NULL) {
3131 disp = dseg_add_unique_address(cd, NULL);
3133 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3134 (constant_classref *) iptr->target,
3137 if (opt_showdisassemble)
3141 disp = dseg_add_address(cd, super->vftbl);
3147 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3148 #if defined(ENABLE_THREADS)
3149 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3151 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3152 M_ALD(REG_ITMP2, REG_PV, disp);
3153 if (s1 != REG_ITMP1) {
3154 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
3155 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3156 #if defined(ENABLE_THREADS)
3157 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3159 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
3161 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3162 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3163 M_ALD(REG_ITMP2, REG_PV, disp);
3164 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3165 #if defined(ENABLE_THREADS)
3166 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3169 M_CMPU(REG_ITMP3, REG_ITMP2);
3171 codegen_add_classcastexception_ref(cd, s1);
3173 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3176 /* array type cast-check */
3178 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3179 M_INTMOVE(s1, rd->argintregs[0]);
3181 if (iptr->val.a == NULL) {
3182 disp = dseg_add_unique_address(cd, NULL);
3184 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3185 (constant_classref *) iptr->target,
3188 if (opt_showdisassemble)
3192 disp = dseg_add_address(cd, iptr->val.a);
3194 M_ALD(rd->argintregs[1], REG_PV, disp);
3195 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3196 M_ALD(REG_ITMP2, REG_PV, disp);
3201 codegen_add_classcastexception_ref(cd, s1);
3203 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3204 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3207 emit_store(jd, iptr, iptr->dst, d);
3210 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3211 /* val.a: (classinfo*) superclass */
3213 /* superclass is an interface:
3215 * return (sub != NULL) &&
3216 * (sub->vftbl->interfacetablelength > super->index) &&
3217 * (sub->vftbl->interfacetable[-super->index] != NULL);
3219 * superclass is a class:
3221 * return ((sub != NULL) && (0
3222 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3223 * super->vftbl->diffvall));
3230 super = (classinfo *) iptr->val.a;
3235 superindex = super->index;
3237 #if defined(ENABLE_THREADS)
3238 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3240 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3241 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3243 M_MOV(s1, REG_ITMP1);
3247 /* calculate interface instanceof code size */
3251 s2 += (opt_showdisassemble ? 1 : 0);
3253 /* calculate class instanceof code size */
3257 s3 += (opt_showdisassemble ? 1 : 0);
3261 /* if class is not resolved, check which code to call */
3263 if (super == NULL) {
3265 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3267 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3269 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
3270 (constant_classref *) iptr->target, disp);
3272 if (opt_showdisassemble)
3275 M_ILD(REG_ITMP3, REG_PV, disp);
3276 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3280 /* interface instanceof code */
3282 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3283 if (super == NULL) {
3284 codegen_addpatchref(cd,
3285 PATCHER_checkcast_instanceof_interface,
3286 (constant_classref *) iptr->target, 0);
3288 if (opt_showdisassemble)
3296 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3297 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3298 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3300 M_ALD(REG_ITMP1, REG_ITMP1,
3301 OFFSET(vftbl_t, interfacetable[0]) -
3302 superindex * sizeof(methodptr*));
3305 M_IADD_IMM(REG_ZERO, 1, d);
3311 /* class instanceof code */
3313 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3314 if (super == NULL) {
3315 disp = dseg_add_unique_address(cd, NULL);
3317 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3318 (constant_classref *) iptr->target,
3321 if (opt_showdisassemble)
3325 disp = dseg_add_address(cd, super->vftbl);
3331 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3332 M_ALD(REG_ITMP2, REG_PV, disp);
3333 #if defined(ENABLE_THREADS)
3334 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3336 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3337 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3338 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3339 #if defined(ENABLE_THREADS)
3340 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3342 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3343 M_CMPU(REG_ITMP1, REG_ITMP2);
3346 M_IADD_IMM(REG_ZERO, 1, d);
3348 emit_store(jd, iptr, iptr->dst, d);
3352 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3353 /* op1 = dimension, val.a = class */
3355 /* check for negative sizes and copy sizes to stack if necessary */
3357 MCODECHECK((iptr->op1 << 1) + 64);
3359 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3360 /* copy SAVEDVAR sizes to stack */
3362 if (src->varkind != ARGVAR) {
3363 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3364 #if defined(__DARWIN__)
3365 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
3367 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
3372 /* a0 = dimension count */
3374 ICONST(rd->argintregs[0], iptr->op1);
3376 /* is patcher function set? */
3378 if (iptr->val.a == NULL) {
3379 disp = dseg_add_unique_address(cd, NULL);
3381 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3382 (constant_classref *) iptr->target, disp);
3384 if (opt_showdisassemble)
3388 disp = dseg_add_address(cd, iptr->val.a);
3390 /* a1 = arraydescriptor */
3392 M_ALD(rd->argintregs[1], REG_PV, disp);
3394 /* a2 = pointer to dimensions = stack pointer */
3396 #if defined(__DARWIN__)
3397 M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + INT_ARG_CNT * 4);
3399 M_LDA(rd->argintregs[2], REG_SP, LA_SIZE + 3 * 4);
3402 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3403 M_ALD(REG_ITMP3, REG_PV, disp);
3407 /* check for exception before result assignment */
3409 M_CMPI(REG_RESULT, 0);
3411 codegen_add_fillinstacktrace_ref(cd);
3413 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3414 M_INTMOVE(REG_RESULT, d);
3415 emit_store(jd, iptr, iptr->dst, d);
3420 new_internalerror("Unknown ICMD %d during code generation",
3425 } /* for instruction */
3427 /* copy values to interface registers */
3429 src = bptr->outstack;
3430 len = bptr->outdepth;
3431 MCODECHECK(64 + len);
3432 #if defined(ENABLE_LSRA)
3437 if ((src->varkind != STACKVAR)) {
3439 if (IS_FLT_DBL_TYPE(s2)) {
3440 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3441 if (!(rd->interfaces[len][s2].flags & INMEMORY))
3442 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
3444 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3447 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3448 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3449 if (IS_2_WORD_TYPE(s2))
3450 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
3452 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3455 if (IS_2_WORD_TYPE(s2))
3456 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3458 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3464 } /* if (bptr -> flags >= BBREACHED) */
3465 } /* for basic block */
3467 dseg_createlinenumbertable(cd);
3469 /* generate stubs */
3471 emit_exception_stubs(jd);
3472 emit_patcher_stubs(jd);
3473 emit_replacement_stubs(jd);
3477 /* everything's ok */
3483 /* createcompilerstub **********************************************************
3485 Creates a stub routine which calls the compiler.
3487 *******************************************************************************/
3489 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3490 #define COMPILERSTUB_CODESIZE 4 * 4
3492 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3495 u1 *createcompilerstub(methodinfo *m)
3497 u1 *s; /* memory to hold the stub */
3503 s = CNEW(u1, COMPILERSTUB_SIZE);
3505 /* set data pointer and code pointer */
3508 s = s + COMPILERSTUB_DATASIZE;
3510 /* mark start of dump memory area */
3512 dumpsize = dump_size();
3514 cd = DNEW(codegendata);
3517 /* Store the codeinfo pointer in the same place as in the
3518 methodheader for compiled methods. */
3520 code = code_codeinfo_new(m);
3522 d[0] = (ptrint) asm_call_jit_compiler;
3524 d[2] = (ptrint) code;
3526 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
3527 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
3531 md_cacheflush((u1 *) d, COMPILERSTUB_SIZE);
3533 #if defined(ENABLE_STATISTICS)
3535 count_cstub_len += COMPILERSTUB_SIZE;
3538 /* release dump area */
3540 dump_release(dumpsize);
3546 /* createnativestub ************************************************************
3548 Creates a stub routine which calls a native method.
3550 *******************************************************************************/
3552 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3560 s4 i, j; /* count variables */
3565 /* get required compiler data */
3572 /* set some variables */
3575 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3577 /* calculate stackframe size */
3579 cd->stackframesize =
3580 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3581 sizeof(localref_table) / SIZEOF_VOID_P +
3582 4 + /* 4 stackframeinfo arguments (darwin)*/
3583 nmd->paramcount * 2 + /* assume all arguments are doubles */
3586 /* keep stack 16-byte aligned */
3588 cd->stackframesize = (cd->stackframesize + 3) & ~3;
3590 /* create method header */
3592 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3593 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3594 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3595 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3596 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3597 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3598 (void) dseg_addlinenumbertablesize(cd);
3599 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3604 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
3605 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
3607 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3608 emit_verbosecall_enter(jd);
3610 /* get function address (this must happen before the stackframeinfo) */
3612 funcdisp = dseg_add_functionptr(cd, f);
3614 #if !defined(WITH_STATIC_CLASSPATH)
3616 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp);
3618 if (opt_showdisassemble)
3623 /* save integer and float argument registers */
3627 for (i = 0; i < md->paramcount; i++) {
3628 t = md->paramtypes[i].type;
3630 if (IS_INT_LNG_TYPE(t)) {
3631 if (!md->params[i].inmemory) {
3632 s1 = md->params[i].regoff;
3633 if (IS_2_WORD_TYPE(t)) {
3634 M_IST(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3636 M_IST(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3638 M_IST(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3645 for (i = 0; i < md->paramcount; i++) {
3646 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3647 if (!md->params[i].inmemory) {
3648 s1 = md->params[i].regoff;
3649 M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3655 /* create native stack info */
3657 M_AADD_IMM(REG_SP, cd->stackframesize * 4, rd->argintregs[0]);
3658 M_MOV(REG_PV, rd->argintregs[1]);
3659 M_AADD_IMM(REG_SP, cd->stackframesize * 4, rd->argintregs[2]);
3660 M_ALD(rd->argintregs[3], REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3661 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3662 M_ALD(REG_ITMP1, REG_PV, disp);
3666 /* restore integer and float argument registers */
3670 for (i = 0; i < md->paramcount; i++) {
3671 t = md->paramtypes[i].type;
3673 if (IS_INT_LNG_TYPE(t)) {
3674 if (!md->params[i].inmemory) {
3675 s1 = md->params[i].regoff;
3677 if (IS_2_WORD_TYPE(t)) {
3678 M_ILD(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3680 M_ILD(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3682 M_ILD(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3689 for (i = 0; i < md->paramcount; i++) {
3690 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3691 if (!md->params[i].inmemory) {
3692 s1 = md->params[i].regoff;
3693 M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3699 /* copy or spill arguments to new locations */
3701 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3702 t = md->paramtypes[i].type;
3704 if (IS_INT_LNG_TYPE(t)) {
3705 if (!md->params[i].inmemory) {
3706 if (IS_2_WORD_TYPE(t))
3708 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
3709 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
3711 s1 = rd->argintregs[md->params[i].regoff];
3713 if (!nmd->params[j].inmemory) {
3714 if (IS_2_WORD_TYPE(t)) {
3716 rd->argintregs[GET_LOW_REG(nmd->params[j].regoff)],
3717 rd->argintregs[GET_HIGH_REG(nmd->params[j].regoff)]);
3720 s2 = rd->argintregs[nmd->params[j].regoff];
3725 s2 = nmd->params[j].regoff;
3726 if (IS_2_WORD_TYPE(t))
3727 M_LST(s1, REG_SP, s2 * 4);
3729 M_IST(s1, REG_SP, s2 * 4);
3733 s1 = md->params[i].regoff + cd->stackframesize;
3734 s2 = nmd->params[j].regoff;
3736 M_ILD(REG_ITMP1, REG_SP, s1 * 4);
3737 if (IS_2_WORD_TYPE(t))
3738 M_ILD(REG_ITMP2, REG_SP, s1 * 4 + 4);
3740 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3741 if (IS_2_WORD_TYPE(t))
3742 M_IST(REG_ITMP2, REG_SP, s2 * 4 + 4);
3746 /* We only copy spilled float arguments, as the float
3747 argument registers keep unchanged. */
3749 if (md->params[i].inmemory) {
3750 s1 = md->params[i].regoff + cd->stackframesize;
3751 s2 = nmd->params[j].regoff;
3753 if (IS_2_WORD_TYPE(t)) {
3754 M_DLD(REG_FTMP1, REG_SP, s1 * 4);
3755 M_DST(REG_FTMP1, REG_SP, s2 * 4);
3758 M_FLD(REG_FTMP1, REG_SP, s1 * 4);
3759 M_FST(REG_FTMP1, REG_SP, s2 * 4);
3765 /* put class into second argument register */
3767 if (m->flags & ACC_STATIC) {
3768 disp = dseg_add_address(cd, m->class);
3769 M_ALD(rd->argintregs[1], REG_PV, disp);
3772 /* put env into first argument register */
3774 disp = dseg_add_address(cd, _Jv_env);
3775 M_ALD(rd->argintregs[0], REG_PV, disp);
3777 /* generate the actual native call */
3779 M_ALD(REG_ITMP3, REG_PV, funcdisp);
3783 /* print call trace */
3785 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3786 emit_verbosecall_exit(jd);
3788 /* save return value */
3790 if (md->returntype.type != TYPE_VOID) {
3791 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3792 if (IS_2_WORD_TYPE(md->returntype.type))
3793 M_IST(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3794 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3797 if (IS_2_WORD_TYPE(md->returntype.type))
3798 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3800 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3804 /* remove native stackframe info */
3806 M_AADD_IMM(REG_SP, cd->stackframesize * 4, rd->argintregs[0]);
3807 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3808 M_ALD(REG_ITMP1, REG_PV, disp);
3811 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3813 /* restore return value */
3815 if (md->returntype.type != TYPE_VOID) {
3816 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3817 if (IS_2_WORD_TYPE(md->returntype.type))
3818 M_ILD(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3819 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3822 if (IS_2_WORD_TYPE(md->returntype.type))
3823 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3825 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3829 M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3830 M_MTLR(REG_ITMP2_XPC);
3831 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4); /* remove stackframe */
3833 /* check for exception */
3835 M_TST(REG_ITMP1_XPTR);
3836 M_BNE(1); /* if no exception then return */
3840 /* handle exception */
3842 M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3844 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3845 M_ALD(REG_ITMP3, REG_PV, disp);
3849 /* generate patcher stubs */
3851 emit_patcher_stubs(jd);
3855 return code->entrypoint;
3860 * These are local overrides for various environment variables in Emacs.
3861 * Please do not remove this and leave it at the end of the file, where
3862 * Emacs will automagically detect them.
3863 * ---------------------------------------------------------------------
3866 * indent-tabs-mode: t
3870 * vim:noexpandtab:sw=4:ts=4: