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 5382 2006-09-06 21:17:00Z twisti $
49 #include "vm/jit/powerpc/arch.h"
50 #include "vm/jit/powerpc/codegen.h"
52 #include "mm/memory.h"
53 #include "native/native.h"
55 #if defined(ENABLE_THREADS)
56 # include "threads/native/lock.h"
59 #include "vm/builtin.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
66 #include "vm/jit/abi-asm.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/methodheader.h"
73 #include "vm/jit/parse.h"
74 #include "vm/jit/patcher.h"
75 #include "vm/jit/reg.h"
76 #include "vm/jit/replace.h"
78 #if defined(ENABLE_LSRA)
79 # include "vm/jit/allocator/lsra.h"
83 /* codegen *********************************************************************
85 Generates machine code.
87 *******************************************************************************/
89 bool codegen(jitdata *jd)
95 s4 len, s1, s2, s3, d, disp;
104 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
105 unresolved_method *um;
106 builtintable_entry *bte;
108 rplpoint *replacementpoint;
110 /* get required compiler data */
117 /* prevent compiler warnings */
129 /* space to save used callee saved registers */
131 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
132 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
134 cd->stackframesize = rd->memuse + savedregs_num;
136 #if defined(ENABLE_THREADS)
137 /* Space to save argument of monitor_enter and Return Values to
138 survive monitor_exit. The stack position for the argument can
139 not be shared with place to save the return register on PPC,
140 since both values reside in R3. */
142 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
143 /* reserve 2 slots for long/double return values for monitorexit */
145 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type))
146 cd->stackframesize += 3;
148 cd->stackframesize += 2;
153 /* create method header */
155 /* align stack to 16-bytes */
157 if (!jd->isleafmethod || JITDATA_HAS_FLAG_VERBOSECALL(jd))
158 cd->stackframesize = (cd->stackframesize + 3) & ~3;
160 else if (jd->isleafmethod && (cd->stackframesize == LA_SIZE_IN_POINTERS))
161 cd->stackframesize = 0;
163 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
164 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
166 #if defined(ENABLE_THREADS)
167 /* IsSync contains the offset relative to the stack pointer for the
168 argument of monitor_exit used in the exception handler. Since the
169 offset could be zero and give a wrong meaning of the flag it is
173 if (checksync && (m->flags & ACC_SYNCHRONIZED))
174 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync */
177 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
179 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
180 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
181 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
183 dseg_addlinenumbertablesize(cd);
185 (void) dseg_add_unique_s4(cd, cd->exceptiontablelength); /* ExTableSize */
187 /* create exception table */
189 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
190 dseg_add_target(cd, ex->start);
191 dseg_add_target(cd, ex->end);
192 dseg_add_target(cd, ex->handler);
193 (void) dseg_add_unique_address(cd, ex->catchtype.cls);
196 /* generate method profiling code */
198 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
199 /* count frequency */
201 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
202 M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
203 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
204 M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
206 /* PROFILE_CYCLE_START; */
209 /* create stack frame (if necessary) */
211 if (!jd->isleafmethod) {
213 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
216 if (cd->stackframesize)
217 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
219 /* save return address and used callee saved registers */
221 p = cd->stackframesize;
222 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
223 p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
225 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
226 p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
229 /* take arguments out of register or stack frame */
233 for (p = 0, l = 0; p < md->paramcount; p++) {
234 t = md->paramtypes[p].type;
235 var = &(rd->locals[l][t]);
237 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
241 s1 = md->params[p].regoff;
242 if (IS_INT_LNG_TYPE(t)) { /* integer args */
243 if (IS_2_WORD_TYPE(t))
244 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
245 rd->argintregs[GET_HIGH_REG(s1)]);
247 s2 = rd->argintregs[s1];
248 if (!md->params[p].inmemory) { /* register arguments */
249 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
250 if (IS_2_WORD_TYPE(t))
251 M_LNGMOVE(s2, var->regoff);
253 M_INTMOVE(s2, var->regoff);
255 } else { /* reg arg -> spilled */
256 if (IS_2_WORD_TYPE(t))
257 M_LST(s2, REG_SP, var->regoff * 4);
259 M_IST(s2, REG_SP, var->regoff * 4);
262 } else { /* stack arguments */
263 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
264 if (IS_2_WORD_TYPE(t))
265 M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
267 M_ILD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
269 } else { /* stack arg -> spilled */
271 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
272 M_IST(REG_ITMP1, REG_SP, var->regoff * 4);
273 if (IS_2_WORD_TYPE(t)) {
274 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
275 M_IST(REG_ITMP1, REG_SP, var->regoff * 4 + 4);
278 /* Reuse Memory Position on Caller Stack */
279 var->regoff = cd->stackframesize + s1;
284 } else { /* floating args */
285 if (!md->params[p].inmemory) { /* register arguments */
286 s2 = rd->argfltregs[s1];
287 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
288 M_FLTMOVE(s2, var->regoff);
290 } else { /* reg arg -> spilled */
291 if (IS_2_WORD_TYPE(t))
292 M_DST(s2, REG_SP, var->regoff * 4);
294 M_FST(s2, REG_SP, var->regoff * 4);
297 } else { /* stack arguments */
298 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
299 if (IS_2_WORD_TYPE(t))
300 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
303 M_FLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 4);
305 } else { /* stack-arg -> spilled */
307 if (IS_2_WORD_TYPE(t)) {
308 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
309 M_DST(REG_FTMP1, REG_SP, var->regoff * 4);
310 var->regoff = cd->stackframesize + s1;
313 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
314 M_FST(REG_FTMP1, REG_SP, var->regoff * 4);
317 /* Reuse Memory Position on Caller Stack */
318 var->regoff = cd->stackframesize + s1;
325 #if defined(ENABLE_THREADS)
326 /* call monitorenter function */
328 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
329 /* stack offset for monitor argument */
333 # if !defined(NDEBUG)
334 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
335 M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
337 for (p = 0; p < INT_ARG_CNT; p++)
338 M_IST(rd->argintregs[p], REG_SP, LA_SIZE + p * 8);
340 for (p = 0; p < FLT_ARG_CNT; p++)
341 M_DST(rd->argfltregs[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
343 /* ATTENTION: We multiply here with 2, because we use * 8
344 above for simplicity and below * 4! */
346 s1 += (LA_SIZE_IN_POINTERS + ARG_CNT) * 2;
350 p = dseg_add_functionptr(cd, LOCK_monitor_enter);
351 M_ALD(REG_ITMP3, REG_PV, p);
354 /* get or test the lock object */
356 if (m->flags & ACC_STATIC) {
357 p = dseg_add_address(cd, &m->class->object.header);
358 M_ALD(REG_A0, REG_PV, p);
363 codegen_add_nullpointerexception_ref(cd);
366 M_AST(REG_A0, REG_SP, s1 * 4);
369 # if !defined(NDEBUG)
370 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
371 for (p = 0; p < INT_ARG_CNT; p++)
372 M_ILD(rd->argintregs[p], REG_SP, LA_SIZE + p * 8);
374 for (p = 0; p < FLT_ARG_CNT; p++)
375 M_DLD(rd->argfltregs[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
377 M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
381 #endif /* defined(ENABLE_THREADS) */
383 /* call trace function */
385 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
386 emit_verbosecall_enter(jd);
389 /* end of header generation */
391 replacementpoint = code->rplpoints;
393 /* walk through all basic blocks */
395 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
397 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
399 if (bptr->flags >= BBREACHED) {
401 /* branch resolving */
405 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
406 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
412 /* handle replacement points */
414 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
415 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
420 /* generate basicblock profiling code */
422 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
423 /* count frequency */
425 disp = dseg_add_address(cd, code->bbfrequency);
426 M_ALD(REG_ITMP2, REG_PV, disp);
427 M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
428 M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
429 M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
431 /* if this is an exception handler, start profiling again */
433 /* if (bptr->type == BBTYPE_EXH) */
434 /* PROFILE_CYCLE_START; */
437 /* copy interface registers to their destination */
443 #if defined(ENABLE_LSRA)
445 while (src != NULL) {
447 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
448 /* d = reg_of_var(m, src, REG_ITMP1); */
449 if (!(src->flags & INMEMORY))
453 M_INTMOVE(REG_ITMP1, d);
454 emit_store(jd, NULL, src, d);
460 while (src != NULL) {
462 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
463 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
464 M_INTMOVE(REG_ITMP1, d);
465 emit_store(jd, NULL, src, d);
468 if (src->type == TYPE_LNG)
469 d = codegen_reg_of_var(rd, 0, src, REG_ITMP12_PACKED);
471 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
472 if ((src->varkind != STACKVAR)) {
474 if (IS_FLT_DBL_TYPE(s2)) {
475 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
476 s1 = rd->interfaces[len][s2].regoff;
480 if (IS_2_WORD_TYPE(s2)) {
482 rd->interfaces[len][s2].regoff * 4);
486 rd->interfaces[len][s2].regoff * 4);
489 emit_store(jd, NULL, src, d);
492 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
493 s1 = rd->interfaces[len][s2].regoff;
494 if (IS_2_WORD_TYPE(s2))
500 if (IS_2_WORD_TYPE(s2))
502 rd->interfaces[len][s2].regoff * 4);
505 rd->interfaces[len][s2].regoff * 4);
507 emit_store(jd, NULL, src, d);
514 #if defined(ENABLE_LSRA)
517 /* walk through all instructions */
523 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
524 if (iptr->line != currentline) {
525 dseg_addlinenumber(cd, iptr->line);
526 currentline = iptr->line;
529 MCODECHECK(64); /* an instruction usually needs < 64 words */
532 case ICMD_NOP: /* ... ==> ... */
533 case ICMD_INLINE_START:
534 case ICMD_INLINE_END:
537 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 codegen_add_nullpointerexception_ref(cd);
545 /* constant operations ************************************************/
547 case ICMD_ICONST: /* ... ==> ..., constant */
549 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
550 ICONST(d, iptr->sx.val.i);
551 emit_store_dst(jd, iptr, d);
554 case ICMD_LCONST: /* ... ==> ..., constant */
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
557 LCONST(d, iptr->sx.val.l);
558 emit_store_dst(jd, iptr, d);
561 case ICMD_FCONST: /* ... ==> ..., constant */
563 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
564 a = dseg_add_float(cd, iptr->sx.val.f);
566 emit_store_dst(jd, iptr, d);
569 case ICMD_DCONST: /* ... ==> ..., constant */
571 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
572 a = dseg_add_double(cd, iptr->sx.val.d);
574 emit_store_dst(jd, iptr, d);
577 case ICMD_ACONST: /* ... ==> ..., constant */
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
581 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
582 constant_classref *cr = iptr->sx.val.c.ref;;
584 disp = dseg_add_unique_address(cd, cr);
586 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
589 if (opt_showdisassemble)
593 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
595 M_ALD(d, REG_PV, disp);
596 emit_store_dst(jd, iptr, d);
600 /* load/store operations **********************************************/
602 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
603 case ICMD_ALOAD: /* op1 = local variable */
605 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
607 if ((iptr->dst.var->varkind == LOCALVAR) &&
608 (iptr->dst.var->varnum == iptr->s1.localindex))
610 if (var->flags & INMEMORY)
611 M_ILD(d, REG_SP, var->regoff * 4);
613 M_INTMOVE(var->regoff, d);
614 emit_store_dst(jd, iptr, d);
617 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
618 /* s1.localindex = local variable */
620 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
622 if ((iptr->dst.var->varkind == LOCALVAR) &&
623 (iptr->dst.var->varnum == iptr->s1.localindex))
625 if (var->flags & INMEMORY)
626 M_LLD(d, REG_SP, var->regoff * 4);
628 M_LNGMOVE(var->regoff, d);
629 emit_store_dst(jd, iptr, d);
632 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
633 /* s1.localindex = local variable */
635 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
636 if ((iptr->dst.var->varkind == LOCALVAR) &&
637 (iptr->dst.var->varnum == iptr->s1.localindex))
639 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
640 if (var->flags & INMEMORY)
641 M_FLD(d, REG_SP, var->regoff * 4);
643 M_FLTMOVE(var->regoff, d);
644 emit_store_dst(jd, iptr, d);
647 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
648 /* s1.localindex = local variable */
650 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
651 if ((iptr->dst.var->varkind == LOCALVAR) &&
652 (iptr->dst.var->varnum == iptr->s1.localindex))
654 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
655 if (var->flags & INMEMORY)
656 M_DLD(d, REG_SP, var->regoff * 4);
658 M_FLTMOVE(var->regoff, d);
659 emit_store_dst(jd, iptr, d);
663 case ICMD_ISTORE: /* ..., value ==> ... */
664 case ICMD_ASTORE: /* op1 = local variable */
666 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
668 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
669 if (var->flags & INMEMORY) {
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 M_IST(s1, REG_SP, var->regoff * 4);
673 s1 = emit_load_s1(jd, iptr, var->regoff);
674 M_INTMOVE(s1, var->regoff);
678 case ICMD_LSTORE: /* ..., value ==> ... */
679 /* dst.localindex = local variable */
681 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
683 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
684 if (var->flags & INMEMORY) {
685 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
686 M_LST(s1, REG_SP, var->regoff * 4);
688 s1 = emit_load_s1(jd, iptr, var->regoff);
689 M_LNGMOVE(s1, var->regoff);
693 case ICMD_FSTORE: /* ..., value ==> ... */
694 /* dst.localindex = local variable */
696 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
698 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
699 if (var->flags & INMEMORY) {
700 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
701 M_FST(s1, REG_SP, var->regoff * 4);
703 s1 = emit_load_s1(jd, iptr, var->regoff);
704 M_FLTMOVE(s1, var->regoff);
708 case ICMD_DSTORE: /* ..., value ==> ... */
709 /* dst.localindex = local variable */
711 if ((iptr->s1.var->varkind == LOCALVAR) && (iptr->s1.var->varnum == iptr->dst.localindex))
713 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
714 if (var->flags & INMEMORY) {
715 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
716 M_DST(s1, REG_SP, var->regoff * 4);
718 s1 = emit_load_s1(jd, iptr, var->regoff);
719 M_FLTMOVE(s1, var->regoff);
724 /* pop/dup/swap operations ********************************************/
726 /* attention: double and longs are only one entry in CACAO ICMDs */
728 case ICMD_POP: /* ..., value ==> ... */
729 case ICMD_POP2: /* ..., value, value ==> ... */
732 case ICMD_DUP: /* ..., a ==> ..., a, a */
734 M_COPY(iptr->s1.var, iptr->dst.var);
737 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
739 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
740 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
741 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
744 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
746 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
747 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
748 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
749 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
752 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
754 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
755 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
758 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
760 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
761 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
762 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
763 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
764 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
767 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
769 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
770 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
771 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
772 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
773 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
774 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
777 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
779 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
780 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
784 /* integer operations *************************************************/
786 case ICMD_INEG: /* ..., value ==> ..., - value */
788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_LNEG: /* ..., value ==> ..., - value */
796 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
798 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
799 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
800 emit_store_dst(jd, iptr, d);
803 case ICMD_I2L: /* ..., value ==> ..., value */
805 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
807 M_INTMOVE(s1, GET_LOW_REG(d));
808 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
809 emit_store_dst(jd, iptr, d);
812 case ICMD_L2I: /* ..., value ==> ..., value */
814 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817 emit_store_dst(jd, iptr, d);
820 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
823 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
825 emit_store_dst(jd, iptr, d);
828 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
833 emit_store_dst(jd, iptr, d);
836 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
841 emit_store_dst(jd, iptr, d);
845 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
855 /* sx.val.i = constant */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
859 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
860 M_IADD_IMM(s1, iptr->sx.val.i, d);
862 ICONST(REG_ITMP2, iptr->sx.val.i);
863 M_IADD(s1, REG_ITMP2, d);
865 emit_store_dst(jd, iptr, d);
868 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
870 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
871 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
872 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
873 M_ADDC(s1, s2, GET_LOW_REG(d));
874 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
875 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
876 M_ADDE(s1, s2, GET_HIGH_REG(d));
877 emit_store_dst(jd, iptr, d);
880 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
881 /* sx.val.l = constant */
883 s3 = iptr->sx.val.l & 0xffffffff;
884 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
886 if ((s3 >= -32768) && (s3 <= 32767))
887 M_ADDIC(s1, s3, GET_LOW_REG(d));
889 ICONST(REG_ITMP2, s3);
890 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
892 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
893 s3 = iptr->sx.val.l >> 32;
895 M_ADDME(s1, GET_HIGH_REG(d));
897 M_ADDZE(s1, GET_HIGH_REG(d));
899 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
900 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
902 emit_store_dst(jd, iptr, d);
905 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
908 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
911 emit_store_dst(jd, iptr, d);
914 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
915 /* sx.val.i = constant */
917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
918 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
919 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
920 M_IADD_IMM(s1, -iptr->sx.val.i, d);
922 ICONST(REG_ITMP2, iptr->sx.val.i);
923 M_ISUB(s1, REG_ITMP2, d);
925 emit_store_dst(jd, iptr, d);
928 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
930 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
931 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
932 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
933 M_SUBC(s1, s2, GET_LOW_REG(d));
934 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
935 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
936 M_SUBE(s1, s2, GET_HIGH_REG(d));
937 emit_store_dst(jd, iptr, d);
940 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
941 /* sx.val.l = constant */
943 s3 = (-iptr->sx.val.l) & 0xffffffff;
944 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
945 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
946 if ((s3 >= -32768) && (s3 <= 32767)) {
947 M_ADDIC(s1, s3, GET_LOW_REG(d));
949 ICONST(REG_ITMP2, s3);
950 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
952 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
953 s3 = (-iptr->sx.val.l) >> 32;
955 M_ADDME(s1, GET_HIGH_REG(d));
957 M_ADDZE(s1, GET_HIGH_REG(d));
959 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
960 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
962 emit_store_dst(jd, iptr, d);
965 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
968 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
969 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
972 codegen_add_arithmeticexception_ref(cd);
973 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
974 M_CMP(REG_ITMP3, s1);
975 M_BNE(3 + (s1 != d));
977 M_BNE(1 + (s1 != d));
981 emit_store_dst(jd, iptr, d);
984 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
987 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
991 codegen_add_arithmeticexception_ref(cd);
992 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
993 M_CMP(REG_ITMP3, s1);
999 M_IDIV(s1, s2, REG_ITMP3);
1000 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
1001 M_ISUB(s1, REG_ITMP3, d);
1002 emit_store_dst(jd, iptr, d);
1005 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1006 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1008 bte = iptr->sx.s23.s3.bte;
1011 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1012 M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
1014 codegen_add_arithmeticexception_ref(cd);
1016 disp = dseg_add_functionptr(cd, bte->fp);
1017 M_ALD(REG_ITMP3, REG_PV, disp);
1020 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
1021 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
1024 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1025 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
1026 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
1031 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1032 M_LNGMOVE(REG_RESULT_PACKED, d);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1038 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1039 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1046 /* sx.val.i = constant */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1050 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1051 M_IMUL_IMM(s1, iptr->sx.val.i, d);
1053 ICONST(REG_ITMP3, iptr->sx.val.i);
1054 M_IMUL(s1, REG_ITMP3, d);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1061 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1062 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1063 M_SRA_IMM(s1, iptr->sx.val.i, d);
1065 emit_store_dst(jd, iptr, d);
1068 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1070 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1071 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1072 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1073 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1074 M_SLL(s1, REG_ITMP3, d);
1075 emit_store_dst(jd, iptr, d);
1078 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1079 /* sx.val.i = constant */
1081 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1082 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1083 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1090 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1091 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1092 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1093 M_SRA(s1, REG_ITMP3, d);
1094 emit_store_dst(jd, iptr, d);
1097 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1098 /* sx.val.i = constant */
1100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1101 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1102 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
1103 emit_store_dst(jd, iptr, d);
1106 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1109 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1110 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1111 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1112 M_SRL(s1, REG_ITMP2, d);
1113 emit_store_dst(jd, iptr, d);
1116 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1117 /* sx.val.i = constant */
1119 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1120 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1121 if (iptr->sx.val.i & 0x1f)
1122 M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
1126 emit_store_dst(jd, iptr, d);
1129 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1132 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1139 /* sx.val.i = constant */
1141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1143 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1144 M_AND_IMM(s1, iptr->sx.val.i, d);
1146 else if (iptr->sx.val.i == 0xffffff) {
1147 M_RLWINM(s1, 0, 8, 31, d);
1151 ICONST(REG_ITMP3, iptr->sx.val.i);
1152 M_AND(s1, REG_ITMP3, d);
1154 emit_store_dst(jd, iptr, d);
1157 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1159 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1160 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1162 M_AND(s1, s2, GET_LOW_REG(d));
1163 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1164 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1165 M_AND(s1, s2, GET_HIGH_REG(d));
1166 emit_store_dst(jd, iptr, d);
1169 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1170 /* sx.val.l = constant */
1172 s3 = iptr->sx.val.l & 0xffffffff;
1173 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1174 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1175 if ((s3 >= 0) && (s3 <= 65535))
1176 M_AND_IMM(s1, s3, GET_LOW_REG(d));
1178 ICONST(REG_ITMP3, s3);
1179 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
1181 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1182 s3 = iptr->sx.val.l >> 32;
1183 if ((s3 >= 0) && (s3 <= 65535))
1184 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
1186 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1187 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
1189 emit_store_dst(jd, iptr, d);
1192 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1193 /* sx.val.i = constant */
1195 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1196 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1197 M_MOV(s1, REG_ITMP2);
1199 M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
1200 if (iptr->sx.val.i >= 32768) {
1201 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
1202 M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
1203 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1206 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
1209 int b=0, m = iptr->sx.val.i;
1212 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1214 M_ISUB(s1, REG_ITMP2, d);
1215 emit_store_dst(jd, iptr, d);
1218 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1220 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1221 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1222 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1224 emit_store_dst(jd, iptr, d);
1227 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1228 /* sx.val.i = constant */
1230 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1231 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1232 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1233 M_OR_IMM(s1, iptr->sx.val.i, d);
1235 ICONST(REG_ITMP3, iptr->sx.val.i);
1236 M_OR(s1, REG_ITMP3, d);
1238 emit_store_dst(jd, iptr, d);
1241 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1243 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1244 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1246 M_OR(s1, s2, GET_LOW_REG(d));
1247 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1248 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1249 M_OR(s1, s2, GET_HIGH_REG(d));
1250 emit_store_dst(jd, iptr, d);
1253 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1254 /* sx.val.l = constant */
1256 s3 = iptr->sx.val.l & 0xffffffff;
1257 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1258 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1259 if ((s3 >= 0) && (s3 <= 65535))
1260 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1262 ICONST(REG_ITMP3, s3);
1263 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1265 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1266 s3 = iptr->sx.val.l >> 32;
1267 if ((s3 >= 0) && (s3 <= 65535))
1268 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1270 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1271 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1273 emit_store_dst(jd, iptr, d);
1276 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1279 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1280 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1282 emit_store_dst(jd, iptr, d);
1285 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1286 /* sx.val.i = constant */
1288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1289 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1290 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1291 M_XOR_IMM(s1, iptr->sx.val.i, d);
1293 ICONST(REG_ITMP3, iptr->sx.val.i);
1294 M_XOR(s1, REG_ITMP3, d);
1296 emit_store_dst(jd, iptr, d);
1299 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1301 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1302 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1303 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1304 M_XOR(s1, s2, GET_LOW_REG(d));
1305 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1306 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1307 M_XOR(s1, s2, GET_HIGH_REG(d));
1308 emit_store_dst(jd, iptr, d);
1311 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1312 /* sx.val.l = constant */
1314 s3 = iptr->sx.val.l & 0xffffffff;
1315 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1317 if ((s3 >= 0) && (s3 <= 65535))
1318 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1320 ICONST(REG_ITMP3, s3);
1321 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1323 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1324 s3 = iptr->sx.val.l >> 32;
1325 if ((s3 >= 0) && (s3 <= 65535))
1326 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1328 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1329 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1331 emit_store_dst(jd, iptr, d);
1334 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1335 /*******************************************************************
1336 TODO: CHANGE THIS TO A VERSION THAT WORKS !!!
1337 *******************************************************************/
1338 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1339 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1342 int tempreg = false;
1346 if (iptr->s1.var->flags & INMEMORY) {
1347 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1349 tempreg = tempreg || (d == GET_HIGH_REG(iptr->s1.var->regoff))
1350 || (d == GET_LOW_REG(iptr->s1.var->regoff));
1352 if (iptr->sx.s23.s2.var->flags & INMEMORY) {
1353 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1355 tempreg = tempreg || (d == GET_HIGH_REG(iptr->sx.s23.s2.var->regoff))
1356 || (d == GET_LOW_REG(iptr->sx.s23.s2.var->regoff));
1359 dreg = tempreg ? REG_ITMP1 : d;
1360 M_IADD_IMM(REG_ZERO, 1, dreg);
1365 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1366 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1370 M_IADD_IMM(dreg, -1, dreg);
1371 M_IADD_IMM(dreg, -1, dreg);
1372 gen_resolvebranch(br1, br1, cd->mcodeptr);
1373 gen_resolvebranch(br1 + 1 * 4, br1 + 1 * 4, cd->mcodeptr - 2 * 4);
1376 emit_store_dst(jd, iptr, d);
1379 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1380 /* s1.localindex = variable, sx.val.i = constant*/
1382 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1383 if (var->flags & INMEMORY) {
1385 M_ILD(s1, REG_SP, var->regoff * 4);
1389 u4 m = iptr->sx.val.i;
1393 M_ADDIS(s1, m >> 16, s1);
1395 M_IADD_IMM(s1, m & 0xffff, s1);
1397 if (var->flags & INMEMORY)
1398 M_IST(s1, REG_SP, var->regoff * 4);
1402 /* floating operations ************************************************/
1404 case ICMD_FNEG: /* ..., value ==> ..., - value */
1406 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1407 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1409 emit_store_dst(jd, iptr, d);
1412 case ICMD_DNEG: /* ..., value ==> ..., - value */
1414 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1415 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1417 emit_store_dst(jd, iptr, d);
1420 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1422 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1423 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1424 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1426 emit_store_dst(jd, iptr, d);
1429 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1431 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1432 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1433 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1435 emit_store_dst(jd, iptr, d);
1438 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1440 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1441 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1442 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1444 emit_store_dst(jd, iptr, d);
1447 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1449 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1450 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1451 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1453 emit_store_dst(jd, iptr, d);
1456 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1458 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1459 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1460 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1462 emit_store_dst(jd, iptr, d);
1465 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1467 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1468 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1469 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1471 emit_store_dst(jd, iptr, d);
1474 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1476 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1478 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1480 emit_store_dst(jd, iptr, d);
1483 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1485 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1486 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1487 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1489 emit_store_dst(jd, iptr, d);
1492 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1495 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1496 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1498 disp = dseg_add_float(cd, 0.0);
1499 M_FLD(REG_FTMP2, REG_PV, disp);
1500 M_FCMPU(s1, REG_FTMP2);
1502 disp = dseg_add_unique_s4(cd, 0);
1503 M_CVTDL_C(s1, REG_FTMP1);
1504 M_LDA(REG_ITMP1, REG_PV, disp);
1505 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1506 M_ILD(d, REG_PV, disp);
1507 emit_store_dst(jd, iptr, d);
1510 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1512 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1513 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1515 emit_store_dst(jd, iptr, d);
1518 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1520 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1521 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1523 emit_store_dst(jd, iptr, d);
1526 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1527 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1530 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1531 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1534 M_IADD_IMM(REG_ZERO, -1, d);
1537 M_IADD_IMM(REG_ZERO, 0, d);
1539 M_IADD_IMM(REG_ZERO, 1, d);
1540 emit_store_dst(jd, iptr, d);
1543 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1544 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1546 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1547 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1550 M_IADD_IMM(REG_ZERO, 1, d);
1553 M_IADD_IMM(REG_ZERO, 0, d);
1555 M_IADD_IMM(REG_ZERO, -1, d);
1556 emit_store_dst(jd, iptr, d);
1559 case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */
1560 case ICMD_IF_DCMPEQ:
1562 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1563 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1567 codegen_addreference(cd, iptr->dst.block);
1570 case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */
1571 case ICMD_IF_DCMPNE:
1573 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1574 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1577 codegen_addreference(cd, iptr->dst.block);
1579 codegen_addreference(cd, iptr->dst.block);
1583 case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */
1584 case ICMD_IF_DCMPL_LT:
1586 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1587 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1590 codegen_addreference(cd, iptr->dst.block);
1592 codegen_addreference(cd, iptr->dst.block);
1595 case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */
1596 case ICMD_IF_DCMPL_GT:
1598 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1599 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1603 codegen_addreference(cd, iptr->dst.block);
1606 case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */
1607 case ICMD_IF_DCMPL_LE:
1609 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1610 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1613 codegen_addreference(cd, iptr->dst.block);
1615 codegen_addreference(cd, iptr->dst.block);
1618 case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */
1619 case ICMD_IF_DCMPL_GE:
1621 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1622 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1626 codegen_addreference(cd, iptr->dst.block);
1629 case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */
1630 case ICMD_IF_DCMPG_LT:
1632 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1633 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1637 codegen_addreference(cd, iptr->dst.block);
1640 case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */
1641 case ICMD_IF_DCMPG_GT:
1643 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1644 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1647 codegen_addreference(cd, iptr->dst.block);
1649 codegen_addreference(cd, iptr->dst.block);
1652 case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */
1653 case ICMD_IF_DCMPG_LE:
1655 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1656 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1660 codegen_addreference(cd, iptr->dst.block);
1663 case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */
1664 case ICMD_IF_DCMPG_GE:
1666 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1667 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1670 codegen_addreference(cd, iptr->dst.block);
1672 codegen_addreference(cd, iptr->dst.block);
1676 /* memory operations **************************************************/
1678 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1680 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1682 gen_nullptr_check(s1);
1683 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1684 emit_store_dst(jd, iptr, d);
1687 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1692 if (INSTRUCTION_MUST_CHECK(iptr)) {
1693 gen_nullptr_check(s1);
1696 M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1697 M_LBZX(d, s1, REG_ITMP2);
1699 emit_store_dst(jd, iptr, d);
1702 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1705 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1706 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1707 if (INSTRUCTION_MUST_CHECK(iptr)) {
1708 gen_nullptr_check(s1);
1711 M_SLL_IMM(s2, 1, REG_ITMP2);
1712 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1713 M_LHZX(d, s1, REG_ITMP2);
1714 emit_store_dst(jd, iptr, d);
1717 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1720 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1722 if (INSTRUCTION_MUST_CHECK(iptr)) {
1723 gen_nullptr_check(s1);
1726 M_SLL_IMM(s2, 1, REG_ITMP2);
1727 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1728 M_LHAX(d, s1, REG_ITMP2);
1729 emit_store_dst(jd, iptr, d);
1732 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1737 if (INSTRUCTION_MUST_CHECK(iptr)) {
1738 gen_nullptr_check(s1);
1741 M_SLL_IMM(s2, 2, REG_ITMP2);
1742 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1743 M_LWZX(d, s1, REG_ITMP2);
1744 emit_store_dst(jd, iptr, d);
1747 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1750 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1752 if (INSTRUCTION_MUST_CHECK(iptr)) {
1753 gen_nullptr_check(s1);
1756 M_SLL_IMM(s2, 3, REG_ITMP2);
1757 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1758 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1759 emit_store_dst(jd, iptr, d);
1762 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1765 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1766 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1767 if (INSTRUCTION_MUST_CHECK(iptr)) {
1768 gen_nullptr_check(s1);
1771 M_SLL_IMM(s2, 2, REG_ITMP2);
1772 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1773 M_LFSX(d, s1, REG_ITMP2);
1774 emit_store_dst(jd, iptr, d);
1777 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1779 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1780 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1781 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1782 if (INSTRUCTION_MUST_CHECK(iptr)) {
1783 gen_nullptr_check(s1);
1786 M_SLL_IMM(s2, 3, REG_ITMP2);
1787 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1788 M_LFDX(d, s1, REG_ITMP2);
1789 emit_store_dst(jd, iptr, d);
1792 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1794 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1795 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1797 if (INSTRUCTION_MUST_CHECK(iptr)) {
1798 gen_nullptr_check(s1);
1801 M_SLL_IMM(s2, 2, REG_ITMP2);
1802 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1803 M_LWZX(d, s1, REG_ITMP2);
1804 emit_store_dst(jd, iptr, d);
1808 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1811 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1812 if (INSTRUCTION_MUST_CHECK(iptr)) {
1813 gen_nullptr_check(s1);
1816 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1817 M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1818 M_STBX(s3, s1, REG_ITMP2);
1821 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1824 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1825 if (INSTRUCTION_MUST_CHECK(iptr)) {
1826 gen_nullptr_check(s1);
1829 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1830 M_SLL_IMM(s2, 1, REG_ITMP2);
1831 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1832 M_STHX(s3, s1, REG_ITMP2);
1835 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1838 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1839 if (INSTRUCTION_MUST_CHECK(iptr)) {
1840 gen_nullptr_check(s1);
1843 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1844 M_SLL_IMM(s2, 1, REG_ITMP2);
1845 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1846 M_STHX(s3, s1, REG_ITMP2);
1849 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1852 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1853 if (INSTRUCTION_MUST_CHECK(iptr)) {
1854 gen_nullptr_check(s1);
1857 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1858 M_SLL_IMM(s2, 2, REG_ITMP2);
1859 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1860 M_STWX(s3, s1, REG_ITMP2);
1863 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1867 if (INSTRUCTION_MUST_CHECK(iptr)) {
1868 gen_nullptr_check(s1);
1871 s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1872 M_SLL_IMM(s2, 3, REG_ITMP2);
1873 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
1874 M_STWX(s3, s1, REG_ITMP2);
1875 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1876 s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1877 M_STWX(s3, s1, REG_ITMP2);
1880 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1883 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1884 if (INSTRUCTION_MUST_CHECK(iptr)) {
1885 gen_nullptr_check(s1);
1888 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1889 M_SLL_IMM(s2, 2, REG_ITMP2);
1890 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1891 M_STFSX(s3, s1, REG_ITMP2);
1894 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1897 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1898 if (INSTRUCTION_MUST_CHECK(iptr)) {
1899 gen_nullptr_check(s1);
1902 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1903 M_SLL_IMM(s2, 3, REG_ITMP2);
1904 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1905 M_STFDX(s3, s1, REG_ITMP2);
1908 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1910 s1 = emit_load_s1(jd, iptr, REG_A0);
1911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1912 if (INSTRUCTION_MUST_CHECK(iptr)) {
1913 gen_nullptr_check(s1);
1916 s3 = emit_load_s3(jd, iptr, REG_A1);
1918 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1919 M_ALD(REG_ITMP3, REG_PV, disp);
1922 M_INTMOVE(s1, REG_A0);
1923 M_INTMOVE(s3, REG_A1);
1928 codegen_add_arraystoreexception_ref(cd);
1930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1931 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1932 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1933 M_SLL_IMM(s2, 2, REG_ITMP2);
1934 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1935 M_STWX(s3, s1, REG_ITMP2);
1939 case ICMD_GETSTATIC: /* ... ==> ..., value */
1941 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1942 unresolved_field *uf = iptr->sx.s23.s3.uf;
1944 fieldtype = uf->fieldref->parseddesc.fd->type;
1945 disp = dseg_add_unique_address(cd, uf);
1947 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1949 if (opt_showdisassemble)
1953 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1955 fieldtype = fi->type;
1956 disp = dseg_add_address(cd, &(fi->value));
1958 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1959 codegen_addpatchref(cd, PATCHER_initialize_class,
1962 if (opt_showdisassemble)
1967 M_ALD(REG_ITMP1, REG_PV, disp);
1968 switch (fieldtype) {
1970 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1971 M_ILD_INTERN(d, REG_ITMP1, 0);
1974 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1975 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1976 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1979 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1980 M_ALD_INTERN(d, REG_ITMP1, 0);
1983 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1984 M_FLD_INTERN(d, REG_ITMP1, 0);
1987 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1988 M_DLD_INTERN(d, REG_ITMP1, 0);
1991 emit_store_dst(jd, iptr, d);
1994 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1996 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1997 unresolved_field *uf = iptr->sx.s23.s3.uf;
1999 fieldtype = uf->fieldref->parseddesc.fd->type;
2000 disp = dseg_add_unique_address(cd, uf);
2002 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2004 if (opt_showdisassemble)
2008 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2010 fieldtype = fi->type;
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 (fieldtype) {
2025 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2026 M_IST_INTERN(s1, REG_ITMP1, 0);
2029 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2030 M_LST_INTERN(s1, REG_ITMP1, 0);
2033 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2034 M_AST_INTERN(s1, REG_ITMP1, 0);
2037 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2038 M_FST_INTERN(s1, REG_ITMP1, 0);
2041 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2042 M_DST_INTERN(s1, REG_ITMP1, 0);
2048 case ICMD_GETFIELD: /* ... ==> ..., value */
2050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2051 gen_nullptr_check(s1);
2053 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2054 unresolved_field *uf = iptr->sx.s23.s3.uf;
2056 fieldtype = uf->fieldref->parseddesc.fd->type;
2058 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2060 if (opt_showdisassemble)
2066 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2067 fieldtype = fi->type;
2071 switch (fieldtype) {
2073 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2077 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2078 if (GET_HIGH_REG(d) == s1) {
2079 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2080 M_ILD(GET_HIGH_REG(d), s1, disp);
2083 M_ILD(GET_HIGH_REG(d), s1, disp);
2084 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2092 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2096 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2100 emit_store_dst(jd, iptr, d);
2103 case ICMD_PUTFIELD: /* ..., value ==> ... */
2105 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2106 gen_nullptr_check(s1);
2108 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2109 if (IS_2_WORD_TYPE(fieldtype))
2110 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2112 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2115 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2117 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2118 unresolved_field *uf = iptr->sx.s23.s3.uf;
2120 fieldtype = uf->fieldref->parseddesc.fd->type;
2122 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2124 if (opt_showdisassemble)
2130 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2131 fieldtype = fi->type;
2135 switch (fieldtype) {
2137 M_IST(s2, s1, disp);
2140 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
2141 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
2144 M_AST(s2, s1, disp);
2147 M_FST(s2, s1, disp);
2150 M_DST(s2, s1, disp);
2156 /* branch operations **************************************************/
2158 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2160 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161 M_INTMOVE(s1, REG_ITMP1_XPTR);
2163 #ifdef ENABLE_VERIFIER
2164 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2165 unresolved_class *uc = iptr->sx.s23.s2.uc;
2167 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2169 if (opt_showdisassemble)
2172 #endif /* ENABLE_VERIFIER */
2174 disp = dseg_add_functionptr(cd, asm_handle_exception);
2175 M_ALD(REG_ITMP2, REG_PV, disp);
2178 if (jd->isleafmethod)
2179 M_MFLR(REG_ITMP3); /* save LR */
2181 M_BL(0); /* get current PC */
2182 M_MFLR(REG_ITMP2_XPC);
2184 if (jd->isleafmethod)
2185 M_MTLR(REG_ITMP3); /* restore LR */
2187 M_RTS; /* jump to CTR */
2191 case ICMD_GOTO: /* ... ==> ... */
2193 codegen_addreference(cd, iptr->dst.block);
2197 case ICMD_JSR: /* ... ==> ... */
2199 if (jd->isleafmethod)
2204 M_IADD_IMM(REG_ITMP1, jd->isleafmethod ? 4*4 : 3*4, REG_ITMP1);
2206 if (jd->isleafmethod)
2210 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2213 case ICMD_RET: /* ... ==> ... */
2214 /* s1.localindex = local variable */
2216 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
2217 if (var->flags & INMEMORY) {
2218 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2221 M_MTCTR(var->regoff);
2227 case ICMD_IFNULL: /* ..., value ==> ... */
2229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2232 codegen_addreference(cd, iptr->dst.block);
2235 case ICMD_IFNONNULL: /* ..., value ==> ... */
2237 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2240 codegen_addreference(cd, iptr->dst.block);
2248 case ICMD_IFEQ: /* ..., value ==> ... */
2250 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2251 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2252 M_CMPI(s1, iptr->sx.val.i);
2254 ICONST(REG_ITMP2, iptr->sx.val.i);
2255 M_CMP(s1, REG_ITMP2);
2257 switch (iptr->opc) {
2277 codegen_addreference(cd, iptr->dst.block);
2281 case ICMD_IF_LEQ: /* ..., value ==> ... */
2283 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2284 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2285 if (iptr->sx.val.l == 0) {
2286 M_OR_TST(s1, s2, REG_ITMP3);
2288 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2289 M_XOR_IMM(s2, 0, REG_ITMP2);
2290 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
2291 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2294 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2295 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2296 ICONST(REG_ITMP3, iptr->sx.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, iptr->dst.block);
2304 case ICMD_IF_LLT: /* ..., value ==> ... */
2305 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2306 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2307 if (iptr->sx.val.l == 0) {
2308 /* if high word is less than zero, the whole long is too */
2311 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2314 codegen_addreference(cd, iptr->dst.block);
2316 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2319 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2320 M_CMP(s2, REG_ITMP3);
2322 codegen_addreference(cd, iptr->dst.block);
2324 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2325 M_CMPU(s1, REG_ITMP3);
2328 codegen_addreference(cd, iptr->dst.block);
2331 case ICMD_IF_LLE: /* ..., value ==> ... */
2333 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2334 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2335 /* if (iptr->sx.val.l == 0) { */
2336 /* M_OR(s1, s2, REG_ITMP3); */
2337 /* M_CMPI(REG_ITMP3, 0); */
2340 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2343 codegen_addreference(cd, iptr->dst.block);
2345 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2348 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2349 M_CMP(s2, REG_ITMP3);
2351 codegen_addreference(cd, iptr->dst.block);
2353 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2354 M_CMPU(s1, REG_ITMP3);
2357 codegen_addreference(cd, iptr->dst.block);
2360 case ICMD_IF_LNE: /* ..., value ==> ... */
2362 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2363 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2364 if (iptr->sx.val.l == 0) {
2365 M_OR_TST(s1, s2, REG_ITMP3);
2367 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2368 M_XOR_IMM(s2, 0, REG_ITMP2);
2369 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
2370 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2373 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2374 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2375 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2376 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2377 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2380 codegen_addreference(cd, iptr->dst.block);
2383 case ICMD_IF_LGT: /* ..., value ==> ... */
2385 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2386 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2387 /* if (iptr->sx.val.l == 0) { */
2388 /* M_OR(s1, s2, REG_ITMP3); */
2389 /* M_CMPI(REG_ITMP3, 0); */
2392 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2395 codegen_addreference(cd, iptr->dst.block);
2397 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2400 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2401 M_CMP(s2, REG_ITMP3);
2403 codegen_addreference(cd, iptr->dst.block);
2405 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2406 M_CMPU(s1, REG_ITMP3);
2409 codegen_addreference(cd, iptr->dst.block);
2412 case ICMD_IF_LGE: /* ..., value ==> ... */
2414 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2415 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2416 if (iptr->sx.val.l == 0) {
2417 /* if high word is greater equal zero, the whole long is too */
2420 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2423 codegen_addreference(cd, iptr->dst.block);
2425 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2428 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2429 M_CMP(s2, REG_ITMP3);
2431 codegen_addreference(cd, iptr->dst.block);
2433 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2434 M_CMPU(s1, REG_ITMP3);
2437 codegen_addreference(cd, iptr->dst.block);
2440 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2441 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2443 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2444 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2447 codegen_addreference(cd, iptr->dst.block);
2450 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2452 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2453 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2455 /* load low-bits before the branch, so we know the distance */
2456 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2457 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2461 codegen_addreference(cd, iptr->dst.block);
2464 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2465 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2468 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2471 codegen_addreference(cd, iptr->dst.block);
2474 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2476 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2477 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2480 codegen_addreference(cd, iptr->dst.block);
2481 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2482 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2485 codegen_addreference(cd, iptr->dst.block);
2488 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2490 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2491 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2494 codegen_addreference(cd, iptr->dst.block);
2497 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2499 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2500 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2503 codegen_addreference(cd, iptr->dst.block);
2504 /* load low-bits before the branch, so we know the distance */
2505 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2506 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2510 codegen_addreference(cd, iptr->dst.block);
2513 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2516 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2519 codegen_addreference(cd, iptr->dst.block);
2522 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2524 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2525 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2528 codegen_addreference(cd, iptr->dst.block);
2529 /* load low-bits before the branch, so we know the distance */
2530 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2531 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2535 codegen_addreference(cd, iptr->dst.block);
2538 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2541 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2544 codegen_addreference(cd, iptr->dst.block);
2547 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2549 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2550 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2553 codegen_addreference(cd, iptr->dst.block);
2554 /* load low-bits before the branch, so we know the distance */
2555 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2556 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2560 codegen_addreference(cd, iptr->dst.block);
2563 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2566 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2569 codegen_addreference(cd, iptr->dst.block);
2572 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2574 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2575 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2578 codegen_addreference(cd, iptr->dst.block);
2579 /* load low-bits before the branch, so we know the distance */
2580 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2581 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2585 codegen_addreference(cd, iptr->dst.block);
2588 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2590 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2591 M_INTMOVE(s1, REG_RESULT);
2592 goto nowperformreturn;
2594 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2596 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2597 M_INTMOVE(s1, REG_RESULT);
2599 #ifdef ENABLE_VERIFIER
2600 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2601 unresolved_class *uc = iptr->sx.s23.s2.uc;
2603 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2605 if (opt_showdisassemble)
2608 #endif /* ENABLE_VERIFIER */
2609 goto nowperformreturn;
2611 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2613 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2614 M_LNGMOVE(s1, REG_RESULT_PACKED);
2615 goto nowperformreturn;
2617 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2620 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2621 M_FLTMOVE(s1, REG_FRESULT);
2622 goto nowperformreturn;
2624 case ICMD_RETURN: /* ... ==> ... */
2630 p = cd->stackframesize;
2632 /* call trace function */
2634 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2635 emit_verbosecall_exit(jd);
2637 #if defined(ENABLE_THREADS)
2638 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2639 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2640 M_ALD(REG_ITMP3, REG_PV, disp);
2643 /* we need to save the proper return value */
2645 switch (iptr->opc) {
2647 M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2651 M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2654 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2657 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2661 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
2664 /* and now restore the proper return value */
2666 switch (iptr->opc) {
2668 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2672 M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2675 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2678 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2684 /* restore return address */
2686 if (!jd->isleafmethod) {
2687 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2688 may have a displacement overflow. */
2690 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
2694 /* restore saved registers */
2696 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2697 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2699 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2700 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2703 /* deallocate stack */
2705 if (cd->stackframesize)
2706 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4);
2714 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2717 branch_target_t *table;
2719 table = iptr->dst.table;
2721 l = iptr->sx.s23.s2.tablelow;
2722 i = iptr->sx.s23.s3.tablehigh;
2724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2726 M_INTMOVE(s1, REG_ITMP1);
2727 else if (l <= 32768)
2728 M_LDA(REG_ITMP1, s1, -l);
2730 ICONST(REG_ITMP2, l);
2731 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2738 M_CMPUI(REG_ITMP1, i - 1);
2740 codegen_addreference(cd, table[0].block);
2742 /* build jump table top down and use address of lowest entry */
2747 dseg_add_target(cd, table->block);
2751 /* length of dataseg after last dseg_add_target is used by load */
2753 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2754 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2755 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2763 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2766 lookup_target_t *lookup;
2768 lookup = iptr->dst.lookup;
2770 i = iptr->sx.s23.s2.lookupcount;
2772 MCODECHECK((i<<2)+8);
2773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2776 if ((lookup->value >= -32768) && (lookup->value <= 32767)) {
2777 M_CMPI(s1, lookup->value);
2780 disp = dseg_add_s4(cd, lookup->value);
2781 M_ILD(REG_ITMP2, REG_PV, disp);
2782 M_CMP(s1, REG_ITMP2);
2785 codegen_addreference(cd, lookup->target.block);
2790 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2797 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2799 bte = iptr->sx.s23.s3.bte;
2803 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2805 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2806 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2807 case ICMD_INVOKEINTERFACE:
2809 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2811 um = iptr->sx.s23.s3.um;
2812 md = um->methodref->parseddesc.md;
2815 lm = iptr->sx.s23.s3.fmiref->p.method;
2817 md = lm->parseddesc;
2821 s3 = md->paramcount;
2823 MCODECHECK((s3 << 1) + 64);
2825 /* copy arguments to registers or stack location */
2827 for (s3 = s3 - 1; s3 >= 0; s3--) {
2828 src = iptr->sx.s23.s2.args[s3];
2830 if (src->varkind == ARGVAR)
2833 if (IS_INT_LNG_TYPE(src->type)) {
2834 if (!md->params[s3].inmemory) {
2835 if (IS_2_WORD_TYPE(src->type)) {
2837 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
2838 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]);
2839 d = emit_load(jd, iptr, src, s1);
2843 s1 = rd->argintregs[md->params[s3].regoff];
2844 d = emit_load(jd, iptr, src, s1);
2849 if (IS_2_WORD_TYPE(src->type)) {
2850 d = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
2851 M_LST(d, REG_SP, md->params[s3].regoff * 4);
2854 d = emit_load(jd, iptr, src, REG_ITMP1);
2855 M_IST(d, REG_SP, md->params[s3].regoff * 4);
2860 if (!md->params[s3].inmemory) {
2861 s1 = rd->argfltregs[md->params[s3].regoff];
2862 d = emit_load(jd, iptr, src, s1);
2866 d = emit_load(jd, iptr, src, REG_FTMP1);
2867 if (IS_2_WORD_TYPE(src->type))
2868 M_DST(d, REG_SP, md->params[s3].regoff * 4);
2870 M_FST(d, REG_SP, md->params[s3].regoff * 4);
2875 switch (iptr->opc) {
2877 disp = dseg_add_functionptr(cd, bte->fp);
2879 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
2882 case ICMD_INVOKESPECIAL:
2883 gen_nullptr_check(REG_A0);
2884 M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr */
2887 case ICMD_INVOKESTATIC:
2889 disp = dseg_add_unique_address(cd, um);
2891 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2894 if (opt_showdisassemble)
2898 disp = dseg_add_address(cd, lm->stubroutine);
2900 M_ALD(REG_PV, REG_PV, disp);
2903 case ICMD_INVOKEVIRTUAL:
2904 gen_nullptr_check(REG_A0);
2907 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2909 if (opt_showdisassemble)
2915 s1 = OFFSET(vftbl_t, table[0]) +
2916 sizeof(methodptr) * lm->vftblindex;
2919 M_ALD(REG_METHODPTR, REG_A0,
2920 OFFSET(java_objectheader, vftbl));
2921 M_ALD(REG_PV, REG_METHODPTR, s1);
2924 case ICMD_INVOKEINTERFACE:
2925 gen_nullptr_check(REG_A0);
2928 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2930 if (opt_showdisassemble)
2937 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2938 sizeof(methodptr*) * lm->class->index;
2940 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2943 M_ALD(REG_METHODPTR, REG_A0,
2944 OFFSET(java_objectheader, vftbl));
2945 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2946 M_ALD(REG_PV, REG_METHODPTR, s2);
2950 /* generate the actual call */
2954 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2956 M_LDA(REG_PV, REG_ITMP1, -disp);
2958 /* actually only used for ICMD_BUILTIN */
2960 if (INSTRUCTION_MUST_CHECK(iptr)) {
2961 M_CMPI(REG_RESULT, 0);
2963 codegen_add_fillinstacktrace_ref(cd);
2966 /* store return value */
2968 d = md->returntype.type;
2970 if (d != TYPE_VOID) {
2971 if (IS_INT_LNG_TYPE(d)) {
2972 if (IS_2_WORD_TYPE(d)) {
2973 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2974 M_LNGMOVE(REG_RESULT_PACKED, s1);
2977 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2978 M_INTMOVE(REG_RESULT, s1);
2982 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2983 M_FLTMOVE(REG_FRESULT, s1);
2985 emit_store_dst(jd, iptr, s1);
2990 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2991 /* val.a: (classinfo*) superclass */
2993 /* superclass is an interface:
2995 * OK if ((sub == NULL) ||
2996 * (sub->vftbl->interfacetablelength > super->index) &&
2997 * (sub->vftbl->interfacetable[-super->index] != NULL));
2999 * superclass is a class:
3001 * OK if ((sub == NULL) || (0
3002 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3003 * super->vftbl->diffvall));
3006 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3007 /* object type cast-check */
3012 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3017 super = iptr->sx.s23.s3.c.cls;
3018 superindex = super->index;
3021 #if defined(ENABLE_THREADS)
3022 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3027 /* calculate interface checkcast code size */
3031 s2 += (opt_showdisassemble ? 1 : 0);
3033 /* calculate class checkcast code size */
3035 s3 = 8 + (s1 == REG_ITMP1);
3037 s3 += (opt_showdisassemble ? 1 : 0);
3039 /* if class is not resolved, check which code to call */
3041 if (super == NULL) {
3043 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3045 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3047 codegen_addpatchref(cd,
3048 PATCHER_resolve_classref_to_flags,
3049 iptr->sx.s23.s3.c.ref,
3052 if (opt_showdisassemble)
3055 M_ILD(REG_ITMP2, REG_PV, disp);
3056 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3060 /* interface checkcast code */
3062 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3063 if (super == NULL) {
3064 codegen_addpatchref(cd,
3065 PATCHER_checkcast_instanceof_interface,
3066 iptr->sx.s23.s3.c.ref,
3069 if (opt_showdisassemble)
3077 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3078 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3079 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3081 codegen_add_classcastexception_ref(cd, s1);
3082 M_ALD(REG_ITMP3, REG_ITMP2,
3083 OFFSET(vftbl_t, interfacetable[0]) -
3084 superindex * sizeof(methodptr*));
3087 codegen_add_classcastexception_ref(cd, s1);
3093 /* class checkcast code */
3095 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3096 if (super == NULL) {
3097 disp = dseg_add_unique_address(cd, NULL);
3099 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3100 iptr->sx.s23.s3.c.ref,
3103 if (opt_showdisassemble)
3107 disp = dseg_add_address(cd, super->vftbl);
3113 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3114 #if defined(ENABLE_THREADS)
3115 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3117 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3118 M_ALD(REG_ITMP2, REG_PV, disp);
3119 if (s1 != REG_ITMP1) {
3120 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
3121 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3122 #if defined(ENABLE_THREADS)
3123 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3125 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
3127 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3128 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3129 M_ALD(REG_ITMP2, REG_PV, disp);
3130 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3131 #if defined(ENABLE_THREADS)
3132 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3135 M_CMPU(REG_ITMP3, REG_ITMP2);
3137 codegen_add_classcastexception_ref(cd, s1);
3139 d = codegen_reg_of_dst(jd, iptr, s1);
3142 /* array type cast-check */
3144 s1 = emit_load_s1(jd, iptr, REG_A0);
3145 M_INTMOVE(s1, REG_A0);
3147 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3148 disp = dseg_add_unique_address(cd, NULL);
3150 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3151 iptr->sx.s23.s3.c.ref,
3154 if (opt_showdisassemble)
3158 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3160 M_ALD(REG_A1, REG_PV, disp);
3161 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3162 M_ALD(REG_ITMP2, REG_PV, disp);
3167 codegen_add_classcastexception_ref(cd, s1);
3169 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3170 d = codegen_reg_of_dst(jd, iptr, s1);
3173 emit_store_dst(jd, iptr, d);
3176 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3177 /* val.a: (classinfo*) superclass */
3179 /* superclass is an interface:
3181 * return (sub != NULL) &&
3182 * (sub->vftbl->interfacetablelength > super->index) &&
3183 * (sub->vftbl->interfacetable[-super->index] != NULL);
3185 * superclass is a class:
3187 * return ((sub != NULL) && (0
3188 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3189 * super->vftbl->diffvall));
3196 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3201 super = iptr->sx.s23.s3.c.cls;
3202 superindex = super->index;
3205 #if defined(ENABLE_THREADS)
3206 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3208 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3209 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3211 M_MOV(s1, REG_ITMP1);
3215 /* calculate interface instanceof code size */
3219 s2 += (opt_showdisassemble ? 1 : 0);
3221 /* calculate class instanceof code size */
3225 s3 += (opt_showdisassemble ? 1 : 0);
3229 /* if class is not resolved, check which code to call */
3231 if (super == NULL) {
3233 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3235 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3237 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
3238 iptr->sx.s23.s3.c.ref, disp);
3240 if (opt_showdisassemble)
3243 M_ILD(REG_ITMP3, REG_PV, disp);
3244 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3248 /* interface instanceof code */
3250 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3251 if (super == NULL) {
3252 codegen_addpatchref(cd,
3253 PATCHER_checkcast_instanceof_interface,
3254 iptr->sx.s23.s3.c.ref, 0);
3256 if (opt_showdisassemble)
3264 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3265 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3266 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3268 M_ALD(REG_ITMP1, REG_ITMP1,
3269 OFFSET(vftbl_t, interfacetable[0]) -
3270 superindex * sizeof(methodptr*));
3273 M_IADD_IMM(REG_ZERO, 1, d);
3279 /* class instanceof code */
3281 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3282 if (super == NULL) {
3283 disp = dseg_add_unique_address(cd, NULL);
3285 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3286 iptr->sx.s23.s3.c.ref,
3289 if (opt_showdisassemble)
3293 disp = dseg_add_address(cd, super->vftbl);
3299 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3300 M_ALD(REG_ITMP2, REG_PV, disp);
3301 #if defined(ENABLE_THREADS)
3302 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3304 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3305 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3306 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3307 #if defined(ENABLE_THREADS)
3308 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3310 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3311 M_CMPU(REG_ITMP1, REG_ITMP2);
3314 M_IADD_IMM(REG_ZERO, 1, d);
3316 emit_store_dst(jd, iptr, d);
3320 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3322 /* check for negative sizes and copy sizes to stack if necessary */
3324 MCODECHECK((iptr->s1.argcount << 1) + 64);
3326 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
3327 src = iptr->sx.s23.s2.args[s1];
3329 /* copy SAVEDVAR sizes to stack */
3331 if (src->varkind != ARGVAR) {
3332 s2 = emit_load(jd, iptr, src, REG_ITMP1);
3333 #if defined(__DARWIN__)
3334 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
3336 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
3341 /* a0 = dimension count */
3343 ICONST(REG_A0, iptr->s1.argcount);
3345 /* is patcher function set? */
3347 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3348 disp = dseg_add_unique_address(cd, NULL);
3350 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3351 iptr->sx.s23.s3.c.ref, disp);
3353 if (opt_showdisassemble)
3357 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3359 /* a1 = arraydescriptor */
3361 M_ALD(REG_A1, REG_PV, disp);
3363 /* a2 = pointer to dimensions = stack pointer */
3365 #if defined(__DARWIN__)
3366 M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 4);
3368 M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 4);
3371 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3372 M_ALD(REG_ITMP3, REG_PV, disp);
3376 /* check for exception before result assignment */
3378 M_CMPI(REG_RESULT, 0);
3380 codegen_add_fillinstacktrace_ref(cd);
3382 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3383 M_INTMOVE(REG_RESULT, d);
3384 emit_store_dst(jd, iptr, d);
3389 new_internalerror("Unknown ICMD %d during code generation",
3394 } /* for instruction */
3396 /* copy values to interface registers */
3398 src = bptr->outstack;
3399 len = bptr->outdepth;
3400 MCODECHECK(64 + len);
3401 #if defined(ENABLE_LSRA)
3406 if ((src->varkind != STACKVAR)) {
3408 if (IS_FLT_DBL_TYPE(s2)) {
3409 s1 = emit_load(jd, iptr, src, REG_FTMP1);
3410 if (!(rd->interfaces[len][s2].flags & INMEMORY))
3411 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
3413 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3416 s1 = emit_load(jd, iptr, src, REG_ITMP1);
3417 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3418 if (IS_2_WORD_TYPE(s2))
3419 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
3421 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3424 if (IS_2_WORD_TYPE(s2))
3425 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3427 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3433 } /* if (bptr -> flags >= BBREACHED) */
3434 } /* for basic block */
3436 dseg_createlinenumbertable(cd);
3438 /* generate stubs */
3440 emit_exception_stubs(jd);
3441 emit_patcher_stubs(jd);
3442 emit_replacement_stubs(jd);
3446 /* everything's ok */
3452 /* createcompilerstub **********************************************************
3454 Creates a stub routine which calls the compiler.
3456 *******************************************************************************/
3458 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3459 #define COMPILERSTUB_CODESIZE 4 * 4
3461 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3464 u1 *createcompilerstub(methodinfo *m)
3466 u1 *s; /* memory to hold the stub */
3472 s = CNEW(u1, COMPILERSTUB_SIZE);
3474 /* set data pointer and code pointer */
3477 s = s + COMPILERSTUB_DATASIZE;
3479 /* mark start of dump memory area */
3481 dumpsize = dump_size();
3483 cd = DNEW(codegendata);
3486 /* Store the codeinfo pointer in the same place as in the
3487 methodheader for compiled methods. */
3489 code = code_codeinfo_new(m);
3491 d[0] = (ptrint) asm_call_jit_compiler;
3493 d[2] = (ptrint) code;
3495 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
3496 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
3500 md_cacheflush((u1 *) d, COMPILERSTUB_SIZE);
3502 #if defined(ENABLE_STATISTICS)
3504 count_cstub_len += COMPILERSTUB_SIZE;
3507 /* release dump area */
3509 dump_release(dumpsize);
3515 /* createnativestub ************************************************************
3517 Creates a stub routine which calls a native method.
3519 *******************************************************************************/
3521 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3529 s4 i, j; /* count variables */
3534 /* get required compiler data */
3541 /* set some variables */
3544 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3546 /* calculate stackframe size */
3548 cd->stackframesize =
3549 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3550 sizeof(localref_table) / SIZEOF_VOID_P +
3551 4 + /* 4 stackframeinfo arguments (darwin)*/
3552 nmd->paramcount * 2 + /* assume all arguments are doubles */
3555 /* keep stack 16-byte aligned */
3557 cd->stackframesize = (cd->stackframesize + 3) & ~3;
3559 /* create method header */
3561 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3562 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3563 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3564 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3565 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3566 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3567 (void) dseg_addlinenumbertablesize(cd);
3568 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3573 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
3574 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
3576 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3577 emit_verbosecall_enter(jd);
3579 /* get function address (this must happen before the stackframeinfo) */
3581 funcdisp = dseg_add_functionptr(cd, f);
3583 #if !defined(WITH_STATIC_CLASSPATH)
3585 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp);
3587 if (opt_showdisassemble)
3592 /* save integer and float argument registers */
3596 for (i = 0; i < md->paramcount; i++) {
3597 t = md->paramtypes[i].type;
3599 if (IS_INT_LNG_TYPE(t)) {
3600 if (!md->params[i].inmemory) {
3601 s1 = md->params[i].regoff;
3602 if (IS_2_WORD_TYPE(t)) {
3603 M_IST(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3605 M_IST(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3607 M_IST(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3614 for (i = 0; i < md->paramcount; i++) {
3615 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3616 if (!md->params[i].inmemory) {
3617 s1 = md->params[i].regoff;
3618 M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3624 /* create native stack info */
3626 M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A0);
3627 M_MOV(REG_PV, REG_A1);
3628 M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A2);
3629 M_ALD(REG_A3, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3630 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3631 M_ALD(REG_ITMP1, REG_PV, disp);
3635 /* restore integer and float argument registers */
3639 for (i = 0; i < md->paramcount; i++) {
3640 t = md->paramtypes[i].type;
3642 if (IS_INT_LNG_TYPE(t)) {
3643 if (!md->params[i].inmemory) {
3644 s1 = md->params[i].regoff;
3646 if (IS_2_WORD_TYPE(t)) {
3647 M_ILD(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3649 M_ILD(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3651 M_ILD(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3658 for (i = 0; i < md->paramcount; i++) {
3659 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3660 if (!md->params[i].inmemory) {
3661 s1 = md->params[i].regoff;
3662 M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3668 /* copy or spill arguments to new locations */
3670 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3671 t = md->paramtypes[i].type;
3673 if (IS_INT_LNG_TYPE(t)) {
3674 if (!md->params[i].inmemory) {
3675 if (IS_2_WORD_TYPE(t))
3677 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
3678 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
3680 s1 = rd->argintregs[md->params[i].regoff];
3682 if (!nmd->params[j].inmemory) {
3683 if (IS_2_WORD_TYPE(t)) {
3685 rd->argintregs[GET_LOW_REG(nmd->params[j].regoff)],
3686 rd->argintregs[GET_HIGH_REG(nmd->params[j].regoff)]);
3689 s2 = rd->argintregs[nmd->params[j].regoff];
3694 s2 = nmd->params[j].regoff;
3695 if (IS_2_WORD_TYPE(t))
3696 M_LST(s1, REG_SP, s2 * 4);
3698 M_IST(s1, REG_SP, s2 * 4);
3702 s1 = md->params[i].regoff + cd->stackframesize;
3703 s2 = nmd->params[j].regoff;
3705 M_ILD(REG_ITMP1, REG_SP, s1 * 4);
3706 if (IS_2_WORD_TYPE(t))
3707 M_ILD(REG_ITMP2, REG_SP, s1 * 4 + 4);
3709 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3710 if (IS_2_WORD_TYPE(t))
3711 M_IST(REG_ITMP2, REG_SP, s2 * 4 + 4);
3715 /* We only copy spilled float arguments, as the float
3716 argument registers keep unchanged. */
3718 if (md->params[i].inmemory) {
3719 s1 = md->params[i].regoff + cd->stackframesize;
3720 s2 = nmd->params[j].regoff;
3722 if (IS_2_WORD_TYPE(t)) {
3723 M_DLD(REG_FTMP1, REG_SP, s1 * 4);
3724 M_DST(REG_FTMP1, REG_SP, s2 * 4);
3727 M_FLD(REG_FTMP1, REG_SP, s1 * 4);
3728 M_FST(REG_FTMP1, REG_SP, s2 * 4);
3734 /* put class into second argument register */
3736 if (m->flags & ACC_STATIC) {
3737 disp = dseg_add_address(cd, m->class);
3738 M_ALD(REG_A1, REG_PV, disp);
3741 /* put env into first argument register */
3743 disp = dseg_add_address(cd, _Jv_env);
3744 M_ALD(REG_A0, REG_PV, disp);
3746 /* generate the actual native call */
3748 M_ALD(REG_ITMP3, REG_PV, funcdisp);
3752 /* print call trace */
3754 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3755 emit_verbosecall_exit(jd);
3757 /* save return value */
3759 if (md->returntype.type != TYPE_VOID) {
3760 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3761 if (IS_2_WORD_TYPE(md->returntype.type))
3762 M_IST(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3763 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3766 if (IS_2_WORD_TYPE(md->returntype.type))
3767 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3769 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3773 /* remove native stackframe info */
3775 M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A0);
3776 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3777 M_ALD(REG_ITMP1, REG_PV, disp);
3780 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3782 /* restore return value */
3784 if (md->returntype.type != TYPE_VOID) {
3785 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3786 if (IS_2_WORD_TYPE(md->returntype.type))
3787 M_ILD(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3788 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3791 if (IS_2_WORD_TYPE(md->returntype.type))
3792 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3794 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3798 M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3799 M_MTLR(REG_ITMP2_XPC);
3800 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4); /* remove stackframe */
3802 /* check for exception */
3804 M_TST(REG_ITMP1_XPTR);
3805 M_BNE(1); /* if no exception then return */
3809 /* handle exception */
3811 M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3813 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3814 M_ALD(REG_ITMP3, REG_PV, disp);
3818 /* generate patcher stubs */
3820 emit_patcher_stubs(jd);
3824 return code->entrypoint;
3829 * These are local overrides for various environment variables in Emacs.
3830 * Please do not remove this and leave it at the end of the file, where
3831 * Emacs will automagically detect them.
3832 * ---------------------------------------------------------------------
3835 * indent-tabs-mode: t
3839 * vim:noexpandtab:sw=4:ts=4: