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 5488 2006-09-13 00:21:40Z 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;
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.any);
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 (!IS_INMEMORY(var->flags)) { /* 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 (!IS_INMEMORY(var->flags)) { /* 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 (!IS_INMEMORY(var->flags)) { /* 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 (!IS_INMEMORY(var->flags)) { /* 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 (!IS_INMEMORY(src->flags))
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 (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
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 (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
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 (IS_INMEMORY(var->flags))
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 (IS_INMEMORY(var->flags))
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 (IS_INMEMORY(var->flags))
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 (IS_INMEMORY(var->flags))
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) &&
667 (iptr->s1.var->varnum == iptr->dst.localindex))
669 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
670 if (IS_INMEMORY(var->flags)) {
671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672 M_IST(s1, REG_SP, var->regoff * 4);
674 s1 = emit_load_s1(jd, iptr, var->regoff);
675 M_INTMOVE(s1, var->regoff);
679 case ICMD_LSTORE: /* ..., value ==> ... */
680 /* dst.localindex = local variable */
682 if ((iptr->s1.var->varkind == LOCALVAR) &&
683 (iptr->s1.var->varnum == iptr->dst.localindex))
685 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
686 if (IS_INMEMORY(var->flags)) {
687 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
688 M_LST(s1, REG_SP, var->regoff * 4);
690 s1 = emit_load_s1(jd, iptr, var->regoff);
691 M_LNGMOVE(s1, var->regoff);
695 case ICMD_FSTORE: /* ..., value ==> ... */
696 /* dst.localindex = local variable */
698 if ((iptr->s1.var->varkind == LOCALVAR) &&
699 (iptr->s1.var->varnum == iptr->dst.localindex))
701 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
702 if (IS_INMEMORY(var->flags)) {
703 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
704 M_FST(s1, REG_SP, var->regoff * 4);
706 s1 = emit_load_s1(jd, iptr, var->regoff);
707 M_FLTMOVE(s1, var->regoff);
711 case ICMD_DSTORE: /* ..., value ==> ... */
712 /* dst.localindex = local variable */
714 if ((iptr->s1.var->varkind == LOCALVAR) &&
715 (iptr->s1.var->varnum == iptr->dst.localindex))
717 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
718 if (IS_INMEMORY(var->flags)) {
719 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
720 M_DST(s1, REG_SP, var->regoff * 4);
722 s1 = emit_load_s1(jd, iptr, var->regoff);
723 M_FLTMOVE(s1, var->regoff);
728 /* pop/dup/swap operations ********************************************/
730 /* attention: double and longs are only one entry in CACAO ICMDs */
732 case ICMD_POP: /* ..., value ==> ... */
733 case ICMD_POP2: /* ..., value, value ==> ... */
736 case ICMD_DUP: /* ..., a ==> ..., a, a */
738 M_COPY(iptr->s1.var, iptr->dst.var);
741 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
743 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
744 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
745 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
748 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
750 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
751 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
752 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
753 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
756 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
758 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
759 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
762 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
764 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
765 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
766 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
767 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
768 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
771 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
773 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
774 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
775 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
776 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
777 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
778 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
781 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
783 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
784 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
788 /* integer operations *************************************************/
790 case ICMD_INEG: /* ..., value ==> ..., - value */
792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
795 emit_store_dst(jd, iptr, d);
798 case ICMD_LNEG: /* ..., value ==> ..., - value */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
802 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
803 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
804 emit_store_dst(jd, iptr, d);
807 case ICMD_I2L: /* ..., value ==> ..., value */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
811 M_INTMOVE(s1, GET_LOW_REG(d));
812 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
813 emit_store_dst(jd, iptr, d);
816 case ICMD_L2I: /* ..., value ==> ..., value */
818 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
829 emit_store_dst(jd, iptr, d);
832 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
834 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
837 emit_store_dst(jd, iptr, d);
840 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
842 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
843 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
845 emit_store_dst(jd, iptr, d);
849 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
853 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855 emit_store_dst(jd, iptr, d);
858 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
859 /* sx.val.i = constant */
861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
862 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
863 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
864 M_IADD_IMM(s1, iptr->sx.val.i, d);
866 ICONST(REG_ITMP2, iptr->sx.val.i);
867 M_IADD(s1, REG_ITMP2, d);
869 emit_store_dst(jd, iptr, d);
872 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
874 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
875 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
876 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
877 M_ADDC(s1, s2, GET_LOW_REG(d));
878 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
879 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
880 M_ADDE(s1, s2, GET_HIGH_REG(d));
881 emit_store_dst(jd, iptr, d);
884 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
885 /* sx.val.l = constant */
887 s3 = iptr->sx.val.l & 0xffffffff;
888 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
889 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
890 if ((s3 >= -32768) && (s3 <= 32767))
891 M_ADDIC(s1, s3, GET_LOW_REG(d));
893 ICONST(REG_ITMP2, s3);
894 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
896 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
897 s3 = iptr->sx.val.l >> 32;
899 M_ADDME(s1, GET_HIGH_REG(d));
901 M_ADDZE(s1, GET_HIGH_REG(d));
903 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
904 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
906 emit_store_dst(jd, iptr, d);
909 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
915 emit_store_dst(jd, iptr, d);
918 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
919 /* sx.val.i = constant */
921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
922 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
923 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
924 M_IADD_IMM(s1, -iptr->sx.val.i, d);
926 ICONST(REG_ITMP2, iptr->sx.val.i);
927 M_ISUB(s1, REG_ITMP2, d);
929 emit_store_dst(jd, iptr, d);
932 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
934 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
935 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
936 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
937 M_SUBC(s1, s2, GET_LOW_REG(d));
938 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
939 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
940 M_SUBE(s1, s2, GET_HIGH_REG(d));
941 emit_store_dst(jd, iptr, d);
944 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
945 /* sx.val.l = constant */
947 s3 = (-iptr->sx.val.l) & 0xffffffff;
948 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
950 if ((s3 >= -32768) && (s3 <= 32767)) {
951 M_ADDIC(s1, s3, GET_LOW_REG(d));
953 ICONST(REG_ITMP2, s3);
954 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
956 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
957 s3 = (-iptr->sx.val.l) >> 32;
959 M_ADDME(s1, GET_HIGH_REG(d));
961 M_ADDZE(s1, GET_HIGH_REG(d));
963 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
964 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
966 emit_store_dst(jd, iptr, d);
969 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
972 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
973 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
976 codegen_add_arithmeticexception_ref(cd);
977 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
978 M_CMP(REG_ITMP3, s1);
979 M_BNE(3 + (s1 != d));
981 M_BNE(1 + (s1 != d));
985 emit_store_dst(jd, iptr, d);
988 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
990 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
991 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
992 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
995 codegen_add_arithmeticexception_ref(cd);
996 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
997 M_CMP(REG_ITMP3, s1);
1003 M_IDIV(s1, s2, REG_ITMP3);
1004 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
1005 M_ISUB(s1, REG_ITMP3, d);
1006 emit_store_dst(jd, iptr, d);
1009 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1010 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1012 bte = iptr->sx.s23.s3.bte;
1015 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
1016 M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
1018 codegen_add_arithmeticexception_ref(cd);
1020 disp = dseg_add_functionptr(cd, bte->fp);
1021 M_ALD(REG_ITMP3, REG_PV, disp);
1024 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
1025 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
1028 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1029 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
1030 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
1035 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1036 M_LNGMOVE(REG_RESULT_PACKED, d);
1037 emit_store_dst(jd, iptr, d);
1040 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1042 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1043 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1044 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1046 emit_store_dst(jd, iptr, d);
1049 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
1050 /* sx.val.i = constant */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1055 M_IMUL_IMM(s1, iptr->sx.val.i, d);
1057 ICONST(REG_ITMP3, iptr->sx.val.i);
1058 M_IMUL(s1, REG_ITMP3, d);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1066 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1067 M_SRA_IMM(s1, iptr->sx.val.i, d);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1077 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1078 M_SLL(s1, REG_ITMP3, d);
1079 emit_store_dst(jd, iptr, d);
1082 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1083 /* sx.val.i = constant */
1085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1086 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1087 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1094 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1095 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1096 M_AND_IMM(s2, 0x1f, REG_ITMP3);
1097 M_SRA(s1, REG_ITMP3, d);
1098 emit_store_dst(jd, iptr, d);
1101 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1102 /* sx.val.i = constant */
1104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1105 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1106 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
1107 emit_store_dst(jd, iptr, d);
1110 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1113 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1114 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1115 M_AND_IMM(s2, 0x1f, REG_ITMP2);
1116 M_SRL(s1, REG_ITMP2, d);
1117 emit_store_dst(jd, iptr, d);
1120 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1121 /* sx.val.i = constant */
1123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1125 if (iptr->sx.val.i & 0x1f)
1126 M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
1130 emit_store_dst(jd, iptr, d);
1133 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1135 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1136 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1137 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1139 emit_store_dst(jd, iptr, d);
1142 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1143 /* sx.val.i = constant */
1145 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1146 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1147 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1148 M_AND_IMM(s1, iptr->sx.val.i, d);
1150 else if (iptr->sx.val.i == 0xffffff) {
1151 M_RLWINM(s1, 0, 8, 31, d);
1155 ICONST(REG_ITMP3, iptr->sx.val.i);
1156 M_AND(s1, REG_ITMP3, d);
1158 emit_store_dst(jd, iptr, d);
1161 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1163 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1164 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1165 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1166 M_AND(s1, s2, GET_LOW_REG(d));
1167 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1168 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1169 M_AND(s1, s2, GET_HIGH_REG(d));
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1174 /* sx.val.l = constant */
1176 s3 = iptr->sx.val.l & 0xffffffff;
1177 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1178 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1179 if ((s3 >= 0) && (s3 <= 65535))
1180 M_AND_IMM(s1, s3, GET_LOW_REG(d));
1182 ICONST(REG_ITMP3, s3);
1183 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
1185 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1186 s3 = iptr->sx.val.l >> 32;
1187 if ((s3 >= 0) && (s3 <= 65535))
1188 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
1190 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1191 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
1193 emit_store_dst(jd, iptr, d);
1196 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1197 /* sx.val.i = constant */
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1200 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1201 M_MOV(s1, REG_ITMP2);
1203 M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
1204 if (iptr->sx.val.i >= 32768) {
1205 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
1206 M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
1207 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1210 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
1213 int b=0, m = iptr->sx.val.i;
1216 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
1218 M_ISUB(s1, REG_ITMP2, d);
1219 emit_store_dst(jd, iptr, d);
1222 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1224 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1225 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1232 /* sx.val.i = constant */
1234 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1236 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1237 M_OR_IMM(s1, iptr->sx.val.i, d);
1239 ICONST(REG_ITMP3, iptr->sx.val.i);
1240 M_OR(s1, REG_ITMP3, d);
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1247 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1248 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1250 M_OR(s1, s2, GET_LOW_REG(d));
1251 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1252 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1253 M_OR(s1, s2, GET_HIGH_REG(d));
1254 emit_store_dst(jd, iptr, d);
1257 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1258 /* sx.val.l = constant */
1260 s3 = iptr->sx.val.l & 0xffffffff;
1261 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1262 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1263 if ((s3 >= 0) && (s3 <= 65535))
1264 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1266 ICONST(REG_ITMP3, s3);
1267 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1269 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1270 s3 = iptr->sx.val.l >> 32;
1271 if ((s3 >= 0) && (s3 <= 65535))
1272 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1274 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1275 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1277 emit_store_dst(jd, iptr, d);
1280 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1283 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1284 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1286 emit_store_dst(jd, iptr, d);
1289 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1290 /* sx.val.i = constant */
1292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1293 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1294 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1295 M_XOR_IMM(s1, iptr->sx.val.i, d);
1297 ICONST(REG_ITMP3, iptr->sx.val.i);
1298 M_XOR(s1, REG_ITMP3, d);
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1305 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1306 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1307 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1308 M_XOR(s1, s2, GET_LOW_REG(d));
1309 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1310 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1311 M_XOR(s1, s2, GET_HIGH_REG(d));
1312 emit_store_dst(jd, iptr, d);
1315 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1316 /* sx.val.l = constant */
1318 s3 = iptr->sx.val.l & 0xffffffff;
1319 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1320 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1321 if ((s3 >= 0) && (s3 <= 65535))
1322 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1324 ICONST(REG_ITMP3, s3);
1325 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1327 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1328 s3 = iptr->sx.val.l >> 32;
1329 if ((s3 >= 0) && (s3 <= 65535))
1330 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1332 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1333 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1335 emit_store_dst(jd, iptr, d);
1338 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1339 /*******************************************************************
1340 TODO: CHANGE THIS TO A VERSION THAT WORKS !!!
1341 *******************************************************************/
1342 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1343 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1344 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1346 int tempreg = false;
1350 if (IS_INMEMORY(iptr->s1.var->flags)) {
1351 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1353 tempreg = tempreg || (d == GET_HIGH_REG(iptr->s1.var->regoff))
1354 || (d == GET_LOW_REG(iptr->s1.var->regoff));
1356 if (IS_INMEMORY(iptr->sx.s23.s2.var->flags)) {
1357 tempreg = tempreg || (d == REG_ITMP3) || (d == REG_ITMP2);
1359 tempreg = tempreg || (d == GET_HIGH_REG(iptr->sx.s23.s2.var->regoff))
1360 || (d == GET_LOW_REG(iptr->sx.s23.s2.var->regoff));
1363 dreg = tempreg ? REG_ITMP1 : d;
1364 M_IADD_IMM(REG_ZERO, 1, dreg);
1369 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1370 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1374 M_IADD_IMM(dreg, -1, dreg);
1375 M_IADD_IMM(dreg, -1, dreg);
1376 gen_resolvebranch(br1, br1, cd->mcodeptr);
1377 gen_resolvebranch(br1 + 1 * 4, br1 + 1 * 4, cd->mcodeptr - 2 * 4);
1380 emit_store_dst(jd, iptr, d);
1383 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1384 /* s1.localindex = variable, sx.val.i = constant*/
1386 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1387 if (IS_INMEMORY(var->flags)) {
1389 M_ILD(s1, REG_SP, var->regoff * 4);
1393 u4 m = iptr->sx.val.i;
1397 M_ADDIS(s1, m >> 16, s1);
1399 M_IADD_IMM(s1, m & 0xffff, s1);
1401 if (IS_INMEMORY(var->flags))
1402 M_IST(s1, REG_SP, var->regoff * 4);
1406 /* floating operations ************************************************/
1408 case ICMD_FNEG: /* ..., value ==> ..., - value */
1410 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1411 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1413 emit_store_dst(jd, iptr, d);
1416 case ICMD_DNEG: /* ..., value ==> ..., - value */
1418 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1419 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1421 emit_store_dst(jd, iptr, d);
1424 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1426 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1427 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1428 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1430 emit_store_dst(jd, iptr, d);
1433 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1435 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1436 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1437 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1439 emit_store_dst(jd, iptr, d);
1442 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1444 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1445 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1446 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1448 emit_store_dst(jd, iptr, d);
1451 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1453 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1454 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1455 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1462 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1464 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1466 emit_store_dst(jd, iptr, d);
1469 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1471 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1472 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1473 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1475 emit_store_dst(jd, iptr, d);
1478 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1480 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1481 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1482 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1484 emit_store_dst(jd, iptr, d);
1487 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1489 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1490 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1491 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1493 emit_store_dst(jd, iptr, d);
1496 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1499 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1502 disp = dseg_add_float(cd, 0.0);
1503 M_FLD(REG_FTMP2, REG_PV, disp);
1504 M_FCMPU(s1, REG_FTMP2);
1506 disp = dseg_add_unique_s4(cd, 0);
1507 M_CVTDL_C(s1, REG_FTMP1);
1508 M_LDA(REG_ITMP1, REG_PV, disp);
1509 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1510 M_ILD(d, REG_PV, disp);
1511 emit_store_dst(jd, iptr, d);
1514 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1516 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1517 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1519 emit_store_dst(jd, iptr, d);
1522 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1524 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1525 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1527 emit_store_dst(jd, iptr, d);
1530 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1531 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1534 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1535 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1536 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1538 M_IADD_IMM(REG_ZERO, -1, d);
1541 M_IADD_IMM(REG_ZERO, 0, d);
1543 M_IADD_IMM(REG_ZERO, 1, d);
1544 emit_store_dst(jd, iptr, d);
1547 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1548 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1550 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1551 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1552 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1554 M_IADD_IMM(REG_ZERO, 1, d);
1557 M_IADD_IMM(REG_ZERO, 0, d);
1559 M_IADD_IMM(REG_ZERO, -1, d);
1560 emit_store_dst(jd, iptr, d);
1563 case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */
1564 case ICMD_IF_DCMPEQ:
1566 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1567 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1571 codegen_addreference(cd, iptr->dst.block);
1574 case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */
1575 case ICMD_IF_DCMPNE:
1577 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1578 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1581 codegen_addreference(cd, iptr->dst.block);
1583 codegen_addreference(cd, iptr->dst.block);
1587 case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */
1588 case ICMD_IF_DCMPL_LT:
1590 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1591 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1594 codegen_addreference(cd, iptr->dst.block);
1596 codegen_addreference(cd, iptr->dst.block);
1599 case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */
1600 case ICMD_IF_DCMPL_GT:
1602 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1603 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1607 codegen_addreference(cd, iptr->dst.block);
1610 case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */
1611 case ICMD_IF_DCMPL_LE:
1613 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1614 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1617 codegen_addreference(cd, iptr->dst.block);
1619 codegen_addreference(cd, iptr->dst.block);
1622 case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */
1623 case ICMD_IF_DCMPL_GE:
1625 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1626 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1630 codegen_addreference(cd, iptr->dst.block);
1633 case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */
1634 case ICMD_IF_DCMPG_LT:
1636 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1637 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1641 codegen_addreference(cd, iptr->dst.block);
1644 case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */
1645 case ICMD_IF_DCMPG_GT:
1647 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1648 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1651 codegen_addreference(cd, iptr->dst.block);
1653 codegen_addreference(cd, iptr->dst.block);
1656 case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */
1657 case ICMD_IF_DCMPG_LE:
1659 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1660 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1664 codegen_addreference(cd, iptr->dst.block);
1667 case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */
1668 case ICMD_IF_DCMPG_GE:
1670 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1671 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1674 codegen_addreference(cd, iptr->dst.block);
1676 codegen_addreference(cd, iptr->dst.block);
1680 /* memory operations **************************************************/
1682 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1685 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1686 gen_nullptr_check(s1);
1687 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1688 emit_store_dst(jd, iptr, d);
1691 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1696 if (INSTRUCTION_MUST_CHECK(iptr)) {
1697 gen_nullptr_check(s1);
1700 M_IADD_IMM(s2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1701 M_LBZX(d, s1, REG_ITMP2);
1703 emit_store_dst(jd, iptr, d);
1706 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1709 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1711 if (INSTRUCTION_MUST_CHECK(iptr)) {
1712 gen_nullptr_check(s1);
1715 M_SLL_IMM(s2, 1, REG_ITMP2);
1716 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1717 M_LHZX(d, s1, REG_ITMP2);
1718 emit_store_dst(jd, iptr, d);
1721 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1724 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1726 if (INSTRUCTION_MUST_CHECK(iptr)) {
1727 gen_nullptr_check(s1);
1730 M_SLL_IMM(s2, 1, REG_ITMP2);
1731 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1732 M_LHAX(d, s1, REG_ITMP2);
1733 emit_store_dst(jd, iptr, d);
1736 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1739 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1741 if (INSTRUCTION_MUST_CHECK(iptr)) {
1742 gen_nullptr_check(s1);
1745 M_SLL_IMM(s2, 2, REG_ITMP2);
1746 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1747 M_LWZX(d, s1, REG_ITMP2);
1748 emit_store_dst(jd, iptr, d);
1751 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1754 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1756 if (INSTRUCTION_MUST_CHECK(iptr)) {
1757 gen_nullptr_check(s1);
1760 M_SLL_IMM(s2, 3, REG_ITMP2);
1761 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1762 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray, data[0]));
1763 emit_store_dst(jd, iptr, d);
1766 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1770 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1771 if (INSTRUCTION_MUST_CHECK(iptr)) {
1772 gen_nullptr_check(s1);
1775 M_SLL_IMM(s2, 2, REG_ITMP2);
1776 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1777 M_LFSX(d, s1, REG_ITMP2);
1778 emit_store_dst(jd, iptr, d);
1781 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1785 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1786 if (INSTRUCTION_MUST_CHECK(iptr)) {
1787 gen_nullptr_check(s1);
1790 M_SLL_IMM(s2, 3, REG_ITMP2);
1791 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1792 M_LFDX(d, s1, REG_ITMP2);
1793 emit_store_dst(jd, iptr, d);
1796 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1798 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1799 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1800 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1801 if (INSTRUCTION_MUST_CHECK(iptr)) {
1802 gen_nullptr_check(s1);
1805 M_SLL_IMM(s2, 2, REG_ITMP2);
1806 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1807 M_LWZX(d, s1, REG_ITMP2);
1808 emit_store_dst(jd, iptr, d);
1812 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1814 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1815 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1816 if (INSTRUCTION_MUST_CHECK(iptr)) {
1817 gen_nullptr_check(s1);
1820 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1821 M_IADD_IMM(s2, OFFSET(java_bytearray, data[0]), REG_ITMP2);
1822 M_STBX(s3, s1, REG_ITMP2);
1825 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1827 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1828 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1829 if (INSTRUCTION_MUST_CHECK(iptr)) {
1830 gen_nullptr_check(s1);
1833 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1834 M_SLL_IMM(s2, 1, REG_ITMP2);
1835 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray, data[0]), REG_ITMP2);
1836 M_STHX(s3, s1, REG_ITMP2);
1839 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1842 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1843 if (INSTRUCTION_MUST_CHECK(iptr)) {
1844 gen_nullptr_check(s1);
1847 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1848 M_SLL_IMM(s2, 1, REG_ITMP2);
1849 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray, data[0]), REG_ITMP2);
1850 M_STHX(s3, s1, REG_ITMP2);
1853 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1856 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1857 if (INSTRUCTION_MUST_CHECK(iptr)) {
1858 gen_nullptr_check(s1);
1861 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1862 M_SLL_IMM(s2, 2, REG_ITMP2);
1863 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray, data[0]), REG_ITMP2);
1864 M_STWX(s3, s1, REG_ITMP2);
1867 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1870 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1871 if (INSTRUCTION_MUST_CHECK(iptr)) {
1872 gen_nullptr_check(s1);
1875 s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1876 M_SLL_IMM(s2, 3, REG_ITMP2);
1877 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray, data[0]), REG_ITMP2);
1878 M_STWX(s3, s1, REG_ITMP2);
1879 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1880 s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1881 M_STWX(s3, s1, REG_ITMP2);
1884 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1887 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1888 if (INSTRUCTION_MUST_CHECK(iptr)) {
1889 gen_nullptr_check(s1);
1892 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1893 M_SLL_IMM(s2, 2, REG_ITMP2);
1894 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray, data[0]), REG_ITMP2);
1895 M_STFSX(s3, s1, REG_ITMP2);
1898 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1900 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1901 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1902 if (INSTRUCTION_MUST_CHECK(iptr)) {
1903 gen_nullptr_check(s1);
1906 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1907 M_SLL_IMM(s2, 3, REG_ITMP2);
1908 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray, data[0]), REG_ITMP2);
1909 M_STFDX(s3, s1, REG_ITMP2);
1912 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1914 s1 = emit_load_s1(jd, iptr, REG_A0);
1915 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1916 if (INSTRUCTION_MUST_CHECK(iptr)) {
1917 gen_nullptr_check(s1);
1920 s3 = emit_load_s3(jd, iptr, REG_A1);
1922 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1923 M_ALD(REG_ITMP3, REG_PV, disp);
1926 M_INTMOVE(s1, REG_A0);
1927 M_INTMOVE(s3, REG_A1);
1932 codegen_add_arraystoreexception_ref(cd);
1934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1935 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1936 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1937 M_SLL_IMM(s2, 2, REG_ITMP2);
1938 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray, data[0]), REG_ITMP2);
1939 M_STWX(s3, s1, REG_ITMP2);
1943 case ICMD_GETSTATIC: /* ... ==> ..., value */
1945 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1946 unresolved_field *uf = iptr->sx.s23.s3.uf;
1948 fieldtype = uf->fieldref->parseddesc.fd->type;
1949 disp = dseg_add_unique_address(cd, uf);
1951 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1953 if (opt_showdisassemble)
1957 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1959 fieldtype = fi->type;
1960 disp = dseg_add_address(cd, &(fi->value));
1962 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1963 codegen_addpatchref(cd, PATCHER_initialize_class,
1966 if (opt_showdisassemble)
1971 M_ALD(REG_ITMP1, REG_PV, disp);
1972 switch (fieldtype) {
1974 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1975 M_ILD_INTERN(d, REG_ITMP1, 0);
1978 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1979 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1980 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1983 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1984 M_ALD_INTERN(d, REG_ITMP1, 0);
1987 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1988 M_FLD_INTERN(d, REG_ITMP1, 0);
1991 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1992 M_DLD_INTERN(d, REG_ITMP1, 0);
1995 emit_store_dst(jd, iptr, d);
1998 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2000 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2001 unresolved_field *uf = iptr->sx.s23.s3.uf;
2003 fieldtype = uf->fieldref->parseddesc.fd->type;
2004 disp = dseg_add_unique_address(cd, uf);
2006 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2008 if (opt_showdisassemble)
2012 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2014 fieldtype = fi->type;
2015 disp = dseg_add_address(cd, &(fi->value));
2017 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2018 codegen_addpatchref(cd, PATCHER_initialize_class,
2021 if (opt_showdisassemble)
2026 M_ALD(REG_ITMP1, REG_PV, disp);
2027 switch (fieldtype) {
2029 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2030 M_IST_INTERN(s1, REG_ITMP1, 0);
2033 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2034 M_LST_INTERN(s1, REG_ITMP1, 0);
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2038 M_AST_INTERN(s1, REG_ITMP1, 0);
2041 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2042 M_FST_INTERN(s1, REG_ITMP1, 0);
2045 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2046 M_DST_INTERN(s1, REG_ITMP1, 0);
2052 case ICMD_GETFIELD: /* ... ==> ..., value */
2054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2055 gen_nullptr_check(s1);
2057 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2058 unresolved_field *uf = iptr->sx.s23.s3.uf;
2060 fieldtype = uf->fieldref->parseddesc.fd->type;
2062 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2064 if (opt_showdisassemble)
2070 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2071 fieldtype = fi->type;
2075 switch (fieldtype) {
2077 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2081 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2082 if (GET_HIGH_REG(d) == s1) {
2083 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2084 M_ILD(GET_HIGH_REG(d), s1, disp);
2087 M_ILD(GET_HIGH_REG(d), s1, disp);
2088 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2096 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2100 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2104 emit_store_dst(jd, iptr, d);
2107 case ICMD_PUTFIELD: /* ..., value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 gen_nullptr_check(s1);
2112 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2113 if (IS_2_WORD_TYPE(fieldtype))
2114 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2119 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2121 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2122 unresolved_field *uf = iptr->sx.s23.s3.uf;
2124 fieldtype = uf->fieldref->parseddesc.fd->type;
2126 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2128 if (opt_showdisassemble)
2134 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2135 fieldtype = fi->type;
2139 switch (fieldtype) {
2141 M_IST(s2, s1, disp);
2144 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
2145 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
2148 M_AST(s2, s1, disp);
2151 M_FST(s2, s1, disp);
2154 M_DST(s2, s1, disp);
2160 /* branch operations **************************************************/
2162 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2164 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2165 M_INTMOVE(s1, REG_ITMP1_XPTR);
2167 #ifdef ENABLE_VERIFIER
2168 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2169 unresolved_class *uc = iptr->sx.s23.s2.uc;
2171 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2173 if (opt_showdisassemble)
2176 #endif /* ENABLE_VERIFIER */
2178 disp = dseg_add_functionptr(cd, asm_handle_exception);
2179 M_ALD(REG_ITMP2, REG_PV, disp);
2182 if (jd->isleafmethod)
2183 M_MFLR(REG_ITMP3); /* save LR */
2185 M_BL(0); /* get current PC */
2186 M_MFLR(REG_ITMP2_XPC);
2188 if (jd->isleafmethod)
2189 M_MTLR(REG_ITMP3); /* restore LR */
2191 M_RTS; /* jump to CTR */
2195 case ICMD_GOTO: /* ... ==> ... */
2197 codegen_addreference(cd, iptr->dst.block);
2201 case ICMD_JSR: /* ... ==> ... */
2203 if (jd->isleafmethod)
2208 M_IADD_IMM(REG_ITMP1, jd->isleafmethod ? 4*4 : 3*4, REG_ITMP1);
2210 if (jd->isleafmethod)
2214 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2217 case ICMD_RET: /* ... ==> ... */
2218 /* s1.localindex = local variable */
2220 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
2221 if (IS_INMEMORY(var->flags)) {
2222 M_ALD(REG_ITMP1, REG_SP, var->regoff * 4);
2226 M_MTCTR(var->regoff);
2231 case ICMD_IFNULL: /* ..., value ==> ... */
2233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2236 codegen_addreference(cd, iptr->dst.block);
2239 case ICMD_IFNONNULL: /* ..., value ==> ... */
2241 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2244 codegen_addreference(cd, iptr->dst.block);
2252 case ICMD_IFEQ: /* ..., value ==> ... */
2254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2255 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2256 M_CMPI(s1, iptr->sx.val.i);
2258 ICONST(REG_ITMP2, iptr->sx.val.i);
2259 M_CMP(s1, REG_ITMP2);
2261 switch (iptr->opc) {
2281 codegen_addreference(cd, iptr->dst.block);
2285 case ICMD_IF_LEQ: /* ..., value ==> ... */
2287 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2288 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2289 if (iptr->sx.val.l == 0) {
2290 M_OR_TST(s1, s2, REG_ITMP3);
2292 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2293 M_XOR_IMM(s2, 0, REG_ITMP2);
2294 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
2295 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2298 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2299 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2300 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2301 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2302 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2305 codegen_addreference(cd, iptr->dst.block);
2308 case ICMD_IF_LLT: /* ..., value ==> ... */
2309 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2310 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2311 if (iptr->sx.val.l == 0) {
2312 /* if high word is less than zero, the whole long is too */
2315 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2318 codegen_addreference(cd, iptr->dst.block);
2320 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2323 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2324 M_CMP(s2, REG_ITMP3);
2326 codegen_addreference(cd, iptr->dst.block);
2328 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2329 M_CMPU(s1, REG_ITMP3);
2332 codegen_addreference(cd, iptr->dst.block);
2335 case ICMD_IF_LLE: /* ..., value ==> ... */
2337 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2338 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2339 /* if (iptr->sx.val.l == 0) { */
2340 /* M_OR(s1, s2, REG_ITMP3); */
2341 /* M_CMPI(REG_ITMP3, 0); */
2344 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2347 codegen_addreference(cd, iptr->dst.block);
2349 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2352 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2353 M_CMP(s2, REG_ITMP3);
2355 codegen_addreference(cd, iptr->dst.block);
2357 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2358 M_CMPU(s1, REG_ITMP3);
2361 codegen_addreference(cd, iptr->dst.block);
2364 case ICMD_IF_LNE: /* ..., value ==> ... */
2366 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2367 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2368 if (iptr->sx.val.l == 0) {
2369 M_OR_TST(s1, s2, REG_ITMP3);
2371 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2372 M_XOR_IMM(s2, 0, REG_ITMP2);
2373 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
2374 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2377 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2378 M_XOR(s1, REG_ITMP3, REG_ITMP1);
2379 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2380 M_XOR(s2, REG_ITMP3, REG_ITMP2);
2381 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
2384 codegen_addreference(cd, iptr->dst.block);
2387 case ICMD_IF_LGT: /* ..., value ==> ... */
2389 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2390 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2391 /* if (iptr->sx.val.l == 0) { */
2392 /* M_OR(s1, s2, REG_ITMP3); */
2393 /* M_CMPI(REG_ITMP3, 0); */
2396 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2399 codegen_addreference(cd, iptr->dst.block);
2401 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2404 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2405 M_CMP(s2, REG_ITMP3);
2407 codegen_addreference(cd, iptr->dst.block);
2409 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2410 M_CMPU(s1, REG_ITMP3);
2413 codegen_addreference(cd, iptr->dst.block);
2416 case ICMD_IF_LGE: /* ..., value ==> ... */
2418 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2419 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2420 if (iptr->sx.val.l == 0) {
2421 /* if high word is greater equal zero, the whole long is too */
2424 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2427 codegen_addreference(cd, iptr->dst.block);
2429 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2432 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2433 M_CMP(s2, REG_ITMP3);
2435 codegen_addreference(cd, iptr->dst.block);
2437 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2438 M_CMPU(s1, REG_ITMP3);
2441 codegen_addreference(cd, iptr->dst.block);
2444 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2445 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2447 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2448 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2451 codegen_addreference(cd, iptr->dst.block);
2454 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2456 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2457 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2459 /* load low-bits before the branch, so we know the distance */
2460 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2461 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2465 codegen_addreference(cd, iptr->dst.block);
2468 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2469 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2471 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2472 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2475 codegen_addreference(cd, iptr->dst.block);
2478 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2480 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2481 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2484 codegen_addreference(cd, iptr->dst.block);
2485 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2486 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2489 codegen_addreference(cd, iptr->dst.block);
2492 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2494 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2495 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2498 codegen_addreference(cd, iptr->dst.block);
2501 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2503 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2504 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2507 codegen_addreference(cd, iptr->dst.block);
2508 /* load low-bits before the branch, so we know the distance */
2509 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2510 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2514 codegen_addreference(cd, iptr->dst.block);
2517 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2520 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2523 codegen_addreference(cd, iptr->dst.block);
2526 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2528 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2529 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2532 codegen_addreference(cd, iptr->dst.block);
2533 /* load low-bits before the branch, so we know the distance */
2534 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2535 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2539 codegen_addreference(cd, iptr->dst.block);
2542 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2545 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2548 codegen_addreference(cd, iptr->dst.block);
2551 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2553 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2554 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2557 codegen_addreference(cd, iptr->dst.block);
2558 /* load low-bits before the branch, so we know the distance */
2559 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2560 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2564 codegen_addreference(cd, iptr->dst.block);
2567 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2570 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2573 codegen_addreference(cd, iptr->dst.block);
2576 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2578 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2579 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2582 codegen_addreference(cd, iptr->dst.block);
2583 /* load low-bits before the branch, so we know the distance */
2584 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2585 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2589 codegen_addreference(cd, iptr->dst.block);
2592 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2594 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2595 M_INTMOVE(s1, REG_RESULT);
2596 goto nowperformreturn;
2598 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2600 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2601 M_INTMOVE(s1, REG_RESULT);
2603 #ifdef ENABLE_VERIFIER
2604 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2605 unresolved_class *uc = iptr->sx.s23.s2.uc;
2607 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2609 if (opt_showdisassemble)
2612 #endif /* ENABLE_VERIFIER */
2613 goto nowperformreturn;
2615 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2617 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2618 M_LNGMOVE(s1, REG_RESULT_PACKED);
2619 goto nowperformreturn;
2621 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2624 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2625 M_FLTMOVE(s1, REG_FRESULT);
2626 goto nowperformreturn;
2628 case ICMD_RETURN: /* ... ==> ... */
2634 p = cd->stackframesize;
2636 /* call trace function */
2638 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2639 emit_verbosecall_exit(jd);
2641 #if defined(ENABLE_THREADS)
2642 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2643 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2644 M_ALD(REG_ITMP3, REG_PV, disp);
2647 /* we need to save the proper return value */
2649 switch (iptr->opc) {
2651 M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2655 M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2658 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2661 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2665 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
2668 /* and now restore the proper return value */
2670 switch (iptr->opc) {
2672 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2676 M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2679 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2682 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2688 /* restore return address */
2690 if (!jd->isleafmethod) {
2691 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2692 may have a displacement overflow. */
2694 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
2698 /* restore saved registers */
2700 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2701 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2703 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2704 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2707 /* deallocate stack */
2709 if (cd->stackframesize)
2710 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4);
2718 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2721 branch_target_t *table;
2723 table = iptr->dst.table;
2725 l = iptr->sx.s23.s2.tablelow;
2726 i = iptr->sx.s23.s3.tablehigh;
2728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2730 M_INTMOVE(s1, REG_ITMP1);
2731 else if (l <= 32768)
2732 M_LDA(REG_ITMP1, s1, -l);
2734 ICONST(REG_ITMP2, l);
2735 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2742 M_CMPUI(REG_ITMP1, i - 1);
2744 codegen_addreference(cd, table[0].block);
2746 /* build jump table top down and use address of lowest entry */
2751 dseg_add_target(cd, table->block);
2755 /* length of dataseg after last dseg_add_target is used by load */
2757 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2758 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2759 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2767 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2770 lookup_target_t *lookup;
2772 lookup = iptr->dst.lookup;
2774 i = iptr->sx.s23.s2.lookupcount;
2776 MCODECHECK((i<<2)+8);
2777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2780 if ((lookup->value >= -32768) && (lookup->value <= 32767)) {
2781 M_CMPI(s1, lookup->value);
2784 disp = dseg_add_s4(cd, lookup->value);
2785 M_ILD(REG_ITMP2, REG_PV, disp);
2786 M_CMP(s1, REG_ITMP2);
2789 codegen_addreference(cd, lookup->target.block);
2794 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2801 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2803 bte = iptr->sx.s23.s3.bte;
2807 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2809 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2810 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2811 case ICMD_INVOKEINTERFACE:
2813 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2815 um = iptr->sx.s23.s3.um;
2816 md = um->methodref->parseddesc.md;
2819 lm = iptr->sx.s23.s3.fmiref->p.method;
2821 md = lm->parseddesc;
2825 s3 = md->paramcount;
2827 MCODECHECK((s3 << 1) + 64);
2829 /* copy arguments to registers or stack location */
2831 for (s3 = s3 - 1; s3 >= 0; s3--) {
2832 src = iptr->sx.s23.s2.args[s3];
2834 if (src->varkind == ARGVAR)
2837 if (IS_INT_LNG_TYPE(src->type)) {
2838 if (!md->params[s3].inmemory) {
2839 if (IS_2_WORD_TYPE(src->type)) {
2841 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
2842 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]);
2843 d = emit_load(jd, iptr, src, s1);
2847 s1 = rd->argintregs[md->params[s3].regoff];
2848 d = emit_load(jd, iptr, src, s1);
2853 if (IS_2_WORD_TYPE(src->type)) {
2854 d = emit_load(jd, iptr, src, REG_ITMP12_PACKED);
2855 M_LST(d, REG_SP, md->params[s3].regoff * 4);
2858 d = emit_load(jd, iptr, src, REG_ITMP1);
2859 M_IST(d, REG_SP, md->params[s3].regoff * 4);
2864 if (!md->params[s3].inmemory) {
2865 s1 = rd->argfltregs[md->params[s3].regoff];
2866 d = emit_load(jd, iptr, src, s1);
2870 d = emit_load(jd, iptr, src, REG_FTMP1);
2871 if (IS_2_WORD_TYPE(src->type))
2872 M_DST(d, REG_SP, md->params[s3].regoff * 4);
2874 M_FST(d, REG_SP, md->params[s3].regoff * 4);
2879 switch (iptr->opc) {
2881 disp = dseg_add_functionptr(cd, bte->fp);
2883 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
2886 case ICMD_INVOKESPECIAL:
2887 gen_nullptr_check(REG_A0);
2888 M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr */
2891 case ICMD_INVOKESTATIC:
2893 disp = dseg_add_unique_address(cd, um);
2895 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2898 if (opt_showdisassemble)
2902 disp = dseg_add_address(cd, lm->stubroutine);
2904 M_ALD(REG_PV, REG_PV, disp);
2907 case ICMD_INVOKEVIRTUAL:
2908 gen_nullptr_check(REG_A0);
2911 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2913 if (opt_showdisassemble)
2919 s1 = OFFSET(vftbl_t, table[0]) +
2920 sizeof(methodptr) * lm->vftblindex;
2923 M_ALD(REG_METHODPTR, REG_A0,
2924 OFFSET(java_objectheader, vftbl));
2925 M_ALD(REG_PV, REG_METHODPTR, s1);
2928 case ICMD_INVOKEINTERFACE:
2929 gen_nullptr_check(REG_A0);
2932 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2934 if (opt_showdisassemble)
2941 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2942 sizeof(methodptr*) * lm->class->index;
2944 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2947 M_ALD(REG_METHODPTR, REG_A0,
2948 OFFSET(java_objectheader, vftbl));
2949 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2950 M_ALD(REG_PV, REG_METHODPTR, s2);
2954 /* generate the actual call */
2958 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2960 M_LDA(REG_PV, REG_ITMP1, -disp);
2962 /* actually only used for ICMD_BUILTIN */
2964 if (INSTRUCTION_MUST_CHECK(iptr)) {
2965 M_CMPI(REG_RESULT, 0);
2967 codegen_add_fillinstacktrace_ref(cd);
2970 /* store return value */
2972 d = md->returntype.type;
2974 if (d != TYPE_VOID) {
2975 if (IS_INT_LNG_TYPE(d)) {
2976 if (IS_2_WORD_TYPE(d)) {
2977 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2978 M_LNGMOVE(REG_RESULT_PACKED, s1);
2981 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2982 M_INTMOVE(REG_RESULT, s1);
2986 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2987 M_FLTMOVE(REG_FRESULT, s1);
2989 emit_store_dst(jd, iptr, s1);
2994 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2995 /* val.a: (classinfo*) superclass */
2997 /* superclass is an interface:
2999 * OK if ((sub == NULL) ||
3000 * (sub->vftbl->interfacetablelength > super->index) &&
3001 * (sub->vftbl->interfacetable[-super->index] != NULL));
3003 * superclass is a class:
3005 * OK if ((sub == NULL) || (0
3006 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3007 * super->vftbl->diffvall));
3010 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3011 /* object type cast-check */
3016 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3021 super = iptr->sx.s23.s3.c.cls;
3022 superindex = super->index;
3025 #if defined(ENABLE_THREADS)
3026 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3031 /* calculate interface checkcast code size */
3035 s2 += (opt_showdisassemble ? 1 : 0);
3037 /* calculate class checkcast code size */
3039 s3 = 8 + (s1 == REG_ITMP1);
3041 s3 += (opt_showdisassemble ? 1 : 0);
3043 /* if class is not resolved, check which code to call */
3045 if (super == NULL) {
3047 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3049 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3051 codegen_addpatchref(cd,
3052 PATCHER_resolve_classref_to_flags,
3053 iptr->sx.s23.s3.c.ref,
3056 if (opt_showdisassemble)
3059 M_ILD(REG_ITMP2, REG_PV, disp);
3060 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3064 /* interface checkcast code */
3066 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3067 if (super == NULL) {
3068 codegen_addpatchref(cd,
3069 PATCHER_checkcast_instanceof_interface,
3070 iptr->sx.s23.s3.c.ref,
3073 if (opt_showdisassemble)
3081 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3082 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3083 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3085 codegen_add_classcastexception_ref(cd, s1);
3086 M_ALD(REG_ITMP3, REG_ITMP2,
3087 OFFSET(vftbl_t, interfacetable[0]) -
3088 superindex * sizeof(methodptr*));
3091 codegen_add_classcastexception_ref(cd, s1);
3097 /* class checkcast code */
3099 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3100 if (super == NULL) {
3101 disp = dseg_add_unique_address(cd, NULL);
3103 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3104 iptr->sx.s23.s3.c.ref,
3107 if (opt_showdisassemble)
3111 disp = dseg_add_address(cd, super->vftbl);
3117 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3118 #if defined(ENABLE_THREADS)
3119 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3121 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3122 M_ALD(REG_ITMP2, REG_PV, disp);
3123 if (s1 != REG_ITMP1) {
3124 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
3125 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3126 #if defined(ENABLE_THREADS)
3127 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3129 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
3131 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3132 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3133 M_ALD(REG_ITMP2, REG_PV, disp);
3134 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3135 #if defined(ENABLE_THREADS)
3136 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3139 M_CMPU(REG_ITMP3, REG_ITMP2);
3141 codegen_add_classcastexception_ref(cd, s1);
3143 d = codegen_reg_of_dst(jd, iptr, s1);
3146 /* array type cast-check */
3148 s1 = emit_load_s1(jd, iptr, REG_A0);
3149 M_INTMOVE(s1, REG_A0);
3151 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3152 disp = dseg_add_unique_address(cd, NULL);
3154 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3155 iptr->sx.s23.s3.c.ref,
3158 if (opt_showdisassemble)
3162 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3164 M_ALD(REG_A1, REG_PV, disp);
3165 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3166 M_ALD(REG_ITMP2, REG_PV, disp);
3171 codegen_add_classcastexception_ref(cd, s1);
3173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3174 d = codegen_reg_of_dst(jd, iptr, s1);
3177 emit_store_dst(jd, iptr, d);
3180 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3181 /* val.a: (classinfo*) superclass */
3183 /* superclass is an interface:
3185 * return (sub != NULL) &&
3186 * (sub->vftbl->interfacetablelength > super->index) &&
3187 * (sub->vftbl->interfacetable[-super->index] != NULL);
3189 * superclass is a class:
3191 * return ((sub != NULL) && (0
3192 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3193 * super->vftbl->diffvall));
3200 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3205 super = iptr->sx.s23.s3.c.cls;
3206 superindex = super->index;
3209 #if defined(ENABLE_THREADS)
3210 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3213 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3215 M_MOV(s1, REG_ITMP1);
3219 /* calculate interface instanceof code size */
3223 s2 += (opt_showdisassemble ? 1 : 0);
3225 /* calculate class instanceof code size */
3229 s3 += (opt_showdisassemble ? 1 : 0);
3233 /* if class is not resolved, check which code to call */
3235 if (super == NULL) {
3237 M_BEQ(3 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3239 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3241 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
3242 iptr->sx.s23.s3.c.ref, disp);
3244 if (opt_showdisassemble)
3247 M_ILD(REG_ITMP3, REG_PV, disp);
3248 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3252 /* interface instanceof code */
3254 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3255 if (super == NULL) {
3256 codegen_addpatchref(cd,
3257 PATCHER_checkcast_instanceof_interface,
3258 iptr->sx.s23.s3.c.ref, 0);
3260 if (opt_showdisassemble)
3268 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3269 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3270 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
3272 M_ALD(REG_ITMP1, REG_ITMP1,
3273 OFFSET(vftbl_t, interfacetable[0]) -
3274 superindex * sizeof(methodptr*));
3277 M_IADD_IMM(REG_ZERO, 1, d);
3283 /* class instanceof code */
3285 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3286 if (super == NULL) {
3287 disp = dseg_add_unique_address(cd, NULL);
3289 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3290 iptr->sx.s23.s3.c.ref,
3293 if (opt_showdisassemble)
3297 disp = dseg_add_address(cd, super->vftbl);
3303 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3304 M_ALD(REG_ITMP2, REG_PV, disp);
3305 #if defined(ENABLE_THREADS)
3306 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3308 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3309 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3310 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3311 #if defined(ENABLE_THREADS)
3312 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3314 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3315 M_CMPU(REG_ITMP1, REG_ITMP2);
3318 M_IADD_IMM(REG_ZERO, 1, d);
3320 emit_store_dst(jd, iptr, d);
3324 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3326 /* check for negative sizes and copy sizes to stack if necessary */
3328 MCODECHECK((iptr->s1.argcount << 1) + 64);
3330 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
3331 src = iptr->sx.s23.s2.args[s1];
3333 /* copy SAVEDVAR sizes to stack */
3335 if (src->varkind != ARGVAR) {
3336 s2 = emit_load(jd, iptr, src, REG_ITMP1);
3337 #if defined(__DARWIN__)
3338 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
3340 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
3345 /* a0 = dimension count */
3347 ICONST(REG_A0, iptr->s1.argcount);
3349 /* is patcher function set? */
3351 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3352 disp = dseg_add_unique_address(cd, NULL);
3354 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3355 iptr->sx.s23.s3.c.ref, disp);
3357 if (opt_showdisassemble)
3361 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3363 /* a1 = arraydescriptor */
3365 M_ALD(REG_A1, REG_PV, disp);
3367 /* a2 = pointer to dimensions = stack pointer */
3369 #if defined(__DARWIN__)
3370 M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 4);
3372 M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 4);
3375 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3376 M_ALD(REG_ITMP3, REG_PV, disp);
3380 /* check for exception before result assignment */
3382 M_CMPI(REG_RESULT, 0);
3384 codegen_add_fillinstacktrace_ref(cd);
3386 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3387 M_INTMOVE(REG_RESULT, d);
3388 emit_store_dst(jd, iptr, d);
3393 new_internalerror("Unknown ICMD %d during code generation",
3398 } /* for instruction */
3400 /* copy values to interface registers */
3402 src = bptr->outstack;
3403 len = bptr->outdepth;
3404 MCODECHECK(64 + len);
3405 #if defined(ENABLE_LSRA)
3410 if ((src->varkind != STACKVAR)) {
3412 if (IS_FLT_DBL_TYPE(s2)) {
3413 s1 = emit_load(jd, iptr, src, REG_FTMP1);
3414 if (!IS_INMEMORY(rd->interfaces[len][s2].flags))
3415 M_FLTMOVE(s1, rd->interfaces[len][s2].regoff);
3417 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3420 s1 = emit_load(jd, iptr, src, REG_ITMP1);
3421 if (!IS_INMEMORY(rd->interfaces[len][s2].flags)) {
3422 if (IS_2_WORD_TYPE(s2))
3423 M_LNGMOVE(s1, rd->interfaces[len][s2].regoff);
3425 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3428 if (IS_2_WORD_TYPE(s2))
3429 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3431 M_IST(s1, REG_SP, rd->interfaces[len][s2].regoff * 4);
3437 } /* if (bptr -> flags >= BBREACHED) */
3438 } /* for basic block */
3440 dseg_createlinenumbertable(cd);
3442 /* generate stubs */
3444 emit_exception_stubs(jd);
3445 emit_patcher_stubs(jd);
3446 emit_replacement_stubs(jd);
3450 /* everything's ok */
3456 /* createcompilerstub **********************************************************
3458 Creates a stub routine which calls the compiler.
3460 *******************************************************************************/
3462 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3463 #define COMPILERSTUB_CODESIZE 4 * 4
3465 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3468 u1 *createcompilerstub(methodinfo *m)
3470 u1 *s; /* memory to hold the stub */
3476 s = CNEW(u1, COMPILERSTUB_SIZE);
3478 /* set data pointer and code pointer */
3481 s = s + COMPILERSTUB_DATASIZE;
3483 /* mark start of dump memory area */
3485 dumpsize = dump_size();
3487 cd = DNEW(codegendata);
3490 /* Store the codeinfo pointer in the same place as in the
3491 methodheader for compiled methods. */
3493 code = code_codeinfo_new(m);
3495 d[0] = (ptrint) asm_call_jit_compiler;
3497 d[2] = (ptrint) code;
3499 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
3500 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
3504 md_cacheflush((u1 *) d, COMPILERSTUB_SIZE);
3506 #if defined(ENABLE_STATISTICS)
3508 count_cstub_len += COMPILERSTUB_SIZE;
3511 /* release dump area */
3513 dump_release(dumpsize);
3519 /* createnativestub ************************************************************
3521 Creates a stub routine which calls a native method.
3523 *******************************************************************************/
3525 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3533 s4 i, j; /* count variables */
3538 /* get required compiler data */
3545 /* set some variables */
3548 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3550 /* calculate stackframe size */
3552 cd->stackframesize =
3553 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3554 sizeof(localref_table) / SIZEOF_VOID_P +
3555 4 + /* 4 stackframeinfo arguments (darwin)*/
3556 nmd->paramcount * 2 + /* assume all arguments are doubles */
3559 /* keep stack 16-byte aligned */
3561 cd->stackframesize = (cd->stackframesize + 3) & ~3;
3563 /* create method header */
3565 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3566 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3567 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3568 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3569 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3570 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3571 (void) dseg_addlinenumbertablesize(cd);
3572 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3577 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
3578 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 4));
3580 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3581 emit_verbosecall_enter(jd);
3583 /* get function address (this must happen before the stackframeinfo) */
3585 funcdisp = dseg_add_functionptr(cd, f);
3587 #if !defined(WITH_STATIC_CLASSPATH)
3589 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp);
3591 if (opt_showdisassemble)
3596 /* save integer and float argument registers */
3600 for (i = 0; i < md->paramcount; i++) {
3601 t = md->paramtypes[i].type;
3603 if (IS_INT_LNG_TYPE(t)) {
3604 if (!md->params[i].inmemory) {
3605 s1 = md->params[i].regoff;
3606 if (IS_2_WORD_TYPE(t)) {
3607 M_IST(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3609 M_IST(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3611 M_IST(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3618 for (i = 0; i < md->paramcount; i++) {
3619 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3620 if (!md->params[i].inmemory) {
3621 s1 = md->params[i].regoff;
3622 M_DST(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3628 /* create native stack info */
3630 M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A0);
3631 M_MOV(REG_PV, REG_A1);
3632 M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A2);
3633 M_ALD(REG_A3, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3634 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3635 M_ALD(REG_ITMP1, REG_PV, disp);
3639 /* restore integer and float argument registers */
3643 for (i = 0; i < md->paramcount; i++) {
3644 t = md->paramtypes[i].type;
3646 if (IS_INT_LNG_TYPE(t)) {
3647 if (!md->params[i].inmemory) {
3648 s1 = md->params[i].regoff;
3650 if (IS_2_WORD_TYPE(t)) {
3651 M_ILD(rd->argintregs[GET_HIGH_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3653 M_ILD(rd->argintregs[GET_LOW_REG(s1)], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3655 M_ILD(rd->argintregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 4);
3662 for (i = 0; i < md->paramcount; i++) {
3663 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3664 if (!md->params[i].inmemory) {
3665 s1 = md->params[i].regoff;
3666 M_DLD(rd->argfltregs[s1], REG_SP, LA_SIZE + 4 * 4 + j * 8);
3672 /* copy or spill arguments to new locations */
3674 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3675 t = md->paramtypes[i].type;
3677 if (IS_INT_LNG_TYPE(t)) {
3678 if (!md->params[i].inmemory) {
3679 if (IS_2_WORD_TYPE(t))
3681 rd->argintregs[GET_LOW_REG(md->params[i].regoff)],
3682 rd->argintregs[GET_HIGH_REG(md->params[i].regoff)]);
3684 s1 = rd->argintregs[md->params[i].regoff];
3686 if (!nmd->params[j].inmemory) {
3687 if (IS_2_WORD_TYPE(t)) {
3689 rd->argintregs[GET_LOW_REG(nmd->params[j].regoff)],
3690 rd->argintregs[GET_HIGH_REG(nmd->params[j].regoff)]);
3693 s2 = rd->argintregs[nmd->params[j].regoff];
3698 s2 = nmd->params[j].regoff;
3699 if (IS_2_WORD_TYPE(t))
3700 M_LST(s1, REG_SP, s2 * 4);
3702 M_IST(s1, REG_SP, s2 * 4);
3706 s1 = md->params[i].regoff + cd->stackframesize;
3707 s2 = nmd->params[j].regoff;
3709 M_ILD(REG_ITMP1, REG_SP, s1 * 4);
3710 if (IS_2_WORD_TYPE(t))
3711 M_ILD(REG_ITMP2, REG_SP, s1 * 4 + 4);
3713 M_IST(REG_ITMP1, REG_SP, s2 * 4);
3714 if (IS_2_WORD_TYPE(t))
3715 M_IST(REG_ITMP2, REG_SP, s2 * 4 + 4);
3719 /* We only copy spilled float arguments, as the float
3720 argument registers keep unchanged. */
3722 if (md->params[i].inmemory) {
3723 s1 = md->params[i].regoff + cd->stackframesize;
3724 s2 = nmd->params[j].regoff;
3726 if (IS_2_WORD_TYPE(t)) {
3727 M_DLD(REG_FTMP1, REG_SP, s1 * 4);
3728 M_DST(REG_FTMP1, REG_SP, s2 * 4);
3731 M_FLD(REG_FTMP1, REG_SP, s1 * 4);
3732 M_FST(REG_FTMP1, REG_SP, s2 * 4);
3738 /* put class into second argument register */
3740 if (m->flags & ACC_STATIC) {
3741 disp = dseg_add_address(cd, m->class);
3742 M_ALD(REG_A1, REG_PV, disp);
3745 /* put env into first argument register */
3747 disp = dseg_add_address(cd, _Jv_env);
3748 M_ALD(REG_A0, REG_PV, disp);
3750 /* generate the actual native call */
3752 M_ALD(REG_ITMP3, REG_PV, funcdisp);
3756 /* print call trace */
3758 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3759 emit_verbosecall_exit(jd);
3761 /* save return value */
3763 if (md->returntype.type != TYPE_VOID) {
3764 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3765 if (IS_2_WORD_TYPE(md->returntype.type))
3766 M_IST(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3767 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3770 if (IS_2_WORD_TYPE(md->returntype.type))
3771 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3773 M_FST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3777 /* remove native stackframe info */
3779 M_AADD_IMM(REG_SP, cd->stackframesize * 4, REG_A0);
3780 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3781 M_ALD(REG_ITMP1, REG_PV, disp);
3784 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3786 /* restore return value */
3788 if (md->returntype.type != TYPE_VOID) {
3789 if (IS_INT_LNG_TYPE(md->returntype.type)) {
3790 if (IS_2_WORD_TYPE(md->returntype.type))
3791 M_ILD(REG_RESULT2, REG_SP, LA_SIZE + 2 * 4);
3792 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 4);
3795 if (IS_2_WORD_TYPE(md->returntype.type))
3796 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3798 M_FLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 4);
3802 M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 4 + LA_LR_OFFSET);
3803 M_MTLR(REG_ITMP2_XPC);
3804 M_LDA(REG_SP, REG_SP, cd->stackframesize * 4); /* remove stackframe */
3806 /* check for exception */
3808 M_TST(REG_ITMP1_XPTR);
3809 M_BNE(1); /* if no exception then return */
3813 /* handle exception */
3815 M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3817 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3818 M_ALD(REG_ITMP3, REG_PV, disp);
3822 /* generate patcher stubs */
3824 emit_patcher_stubs(jd);
3828 return code->entrypoint;
3833 * These are local overrides for various environment variables in Emacs.
3834 * Please do not remove this and leave it at the end of the file, where
3835 * Emacs will automagically detect them.
3836 * ---------------------------------------------------------------------
3839 * indent-tabs-mode: t
3843 * vim:noexpandtab:sw=4:ts=4: