1 /* src/vm/jit/powerpc/codegen.c - machine code generator for 32-bit PowerPC
3 Copyright (C) 1996-2005, 2006, 2007 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
38 #include "vm/jit/powerpc/arch.h"
39 #include "vm/jit/powerpc/codegen.h"
41 #include "mm/memory.h"
43 #include "native/localref.h"
44 #include "native/native.h"
46 #include "threads/lock-common.h"
48 #include "vm/builtin.h"
49 #include "vm/exceptions.h"
50 #include "vm/global.h"
51 #include "vm/stringlocal.h"
54 #include "vm/jit/abi.h"
55 #include "vm/jit/abi-asm.h"
56 #include "vm/jit/asmpart.h"
57 #include "vm/jit/codegen-common.h"
58 #include "vm/jit/dseg.h"
59 #include "vm/jit/emit-common.h"
60 #include "vm/jit/jit.h"
61 #include "vm/jit/md.h"
62 #include "vm/jit/methodheader.h"
63 #include "vm/jit/parse.h"
64 #include "vm/jit/patcher-common.h"
65 #include "vm/jit/reg.h"
66 #include "vm/jit/replace.h"
67 #include "vm/jit/stacktrace.h"
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
77 /* codegen *********************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen_emit(jitdata *jd)
89 s4 len, s1, s2, s3, d, disp;
96 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
97 unresolved_method *um;
98 builtintable_entry *bte;
101 unresolved_field *uf;
105 /* get required compiler data */
112 /* prevent compiler warnings */
127 /* space to save used callee saved registers */
129 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
130 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
132 cd->stackframesize = rd->memuse + savedregs_num;
134 #if defined(ENABLE_THREADS)
135 /* Space to save argument of monitor_enter and Return Values to
136 survive monitor_exit. The stack position for the argument can
137 not be shared with place to save the return register on PPC,
138 since both values reside in R3. */
140 if (checksync && code_is_synchronized(code))
141 cd->stackframesize += 2;
144 /* create method header */
146 /* align stack to 16-bytes */
148 if (!code_is_leafmethod(code) || JITDATA_HAS_FLAG_VERBOSECALL(jd))
149 ALIGN_2(cd->stackframesize);
151 else if (code_is_leafmethod(code) && (cd->stackframesize == LA_SIZE_IN_POINTERS))
152 cd->stackframesize = 0;
154 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
155 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
157 code->synchronizedoffset = rd->memuse * 8;
159 /* REMOVEME: We still need it for exception handling in assembler. */
161 if (code_is_leafmethod(code))
162 (void) dseg_add_unique_s4(cd, 1);
164 (void) dseg_add_unique_s4(cd, 0);
166 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
167 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
169 dseg_addlinenumbertablesize(cd);
171 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
173 /* create exception table */
175 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
176 dseg_add_target(cd, ex->start);
177 dseg_add_target(cd, ex->end);
178 dseg_add_target(cd, ex->handler);
179 (void) dseg_add_unique_address(cd, ex->catchtype.any);
182 #if defined(ENABLE_PROFILING)
183 /* generate method profiling code */
185 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
186 /* count frequency */
188 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
189 M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
190 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
191 M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
193 /* PROFILE_CYCLE_START; */
197 /* create stack frame (if necessary) */
199 if (!code_is_leafmethod(code)) {
201 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
204 if (cd->stackframesize)
205 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
207 /* save return address and used callee saved registers */
209 p = cd->stackframesize;
210 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
211 p--; M_IST(rd->savintregs[i], REG_SP, p * 8);
213 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
214 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
217 /* take arguments out of register or stack frame */
221 for (p = 0, l = 0; p < md->paramcount; p++) {
222 t = md->paramtypes[p].type;
223 varindex = jd->local_map[l * 5 + t];
226 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
229 if (varindex == UNUSED)
233 s1 = md->params[p].regoff;
235 if (IS_INT_LNG_TYPE(t)) {
236 if (!md->params[p].inmemory) {
237 if (!IS_INMEMORY(var->flags)) {
238 if (IS_2_WORD_TYPE(t))
239 M_LNGMOVE(s1, var->vv.regoff);
241 M_INTMOVE(s1, var->vv.regoff);
244 if (IS_2_WORD_TYPE(t))
245 M_LST(s1, REG_SP, var->vv.regoff);
247 M_IST(s1, REG_SP, var->vv.regoff);
251 if (!IS_INMEMORY(var->flags)) {
252 if (IS_2_WORD_TYPE(t))
253 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
255 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
259 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1);
260 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
261 if (IS_2_WORD_TYPE(t)) {
262 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1 + 4);
263 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
266 /* Reuse Memory Position on Caller Stack */
267 var->vv.regoff = cd->stackframesize * 8 + s1;
273 if (!md->params[p].inmemory) {
274 if (!IS_INMEMORY(var->flags))
275 M_FLTMOVE(s1, var->vv.regoff);
277 M_DST(s1, REG_SP, var->vv.regoff);
280 if (!IS_INMEMORY(var->flags))
281 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
284 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize * 8 + s1);
285 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
287 /* Reuse Memory Position on Caller Stack */
288 var->vv.regoff = cd->stackframesize * 8 + s1;
295 #if defined(ENABLE_THREADS)
296 /* call monitorenter function */
298 if (checksync && code_is_synchronized(code)) {
299 /* stack offset for monitor argument */
303 # if !defined(NDEBUG)
304 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
305 M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
307 for (p = 0; p < INT_ARG_CNT; p++)
308 M_IST(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
310 for (p = 0; p < FLT_ARG_CNT; p++)
311 M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
313 s1 += LA_SIZE_IN_POINTERS + ARG_CNT;
317 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
318 M_ALD(REG_ITMP3, REG_PV, disp);
321 /* get or test the lock object */
323 if (m->flags & ACC_STATIC) {
324 disp = dseg_add_address(cd, &m->class->object.header);
325 M_ALD(REG_A0, REG_PV, disp);
330 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
333 M_AST(REG_A0, REG_SP, s1 * 8);
336 # if !defined(NDEBUG)
337 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
338 for (p = 0; p < INT_ARG_CNT; p++)
339 M_ILD(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
341 for (p = 0; p < FLT_ARG_CNT; p++)
342 M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
344 M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
348 #endif /* defined(ENABLE_THREADS) */
350 /* call trace function */
352 emit_verbosecall_enter(jd);
355 /* end of header generation */
357 /* create replacement points */
359 REPLACEMENT_POINTS_INIT(cd, jd);
361 /* walk through all basic blocks */
363 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
365 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
367 if (bptr->flags >= BBREACHED) {
368 /* branch resolving */
370 codegen_resolve_branchrefs(cd, bptr);
372 /* handle replacement points */
374 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
376 #if defined(ENABLE_PROFILING)
377 /* generate basicblock profiling code */
379 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
380 /* count frequency */
382 disp = dseg_add_address(cd, code->bbfrequency);
383 M_ALD(REG_ITMP2, REG_PV, disp);
384 M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
385 M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
386 M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
388 /* if this is an exception handler, start profiling again */
390 /* if (bptr->type == BBTYPE_EXH) */
391 /* PROFILE_CYCLE_START; */
395 /* copy interface registers to their destination */
400 #if defined(ENABLE_LSRA)
402 while (src != NULL) {
404 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
405 /* d = reg_of_var(m, src, REG_ITMP1); */
406 if (!IS_INMEMORY(src->flags))
410 M_INTMOVE(REG_ITMP1, d);
411 emit_store(jd, NULL, src, d);
419 var = VAR(bptr->invars[len]);
420 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
421 d = codegen_reg_of_var(0, var, REG_ITMP1);
422 M_INTMOVE(REG_ITMP1, d);
423 emit_store(jd, NULL, var, d);
426 assert((var->flags & INOUT));
430 #if defined(ENABLE_LSRA)
433 /* walk through all instructions */
438 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
439 if (iptr->line != currentline) {
440 dseg_addlinenumber(cd, iptr->line);
441 currentline = iptr->line;
444 MCODECHECK(64); /* an instruction usually needs < 64 words */
447 case ICMD_NOP: /* ... ==> ... */
448 case ICMD_POP: /* ..., value ==> ... */
449 case ICMD_POP2: /* ..., value, value ==> ... */
452 case ICMD_INLINE_START:
454 REPLACEMENT_POINT_INLINE_START(cd, iptr);
457 case ICMD_INLINE_BODY:
459 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
460 dseg_addlinenumber_inline_start(cd, iptr);
461 dseg_addlinenumber(cd, iptr->line);
464 case ICMD_INLINE_END:
466 dseg_addlinenumber_inline_end(cd, iptr);
467 dseg_addlinenumber(cd, iptr->line);
470 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
473 emit_nullpointer_check(cd, iptr, s1);
476 /* constant operations ************************************************/
478 case ICMD_ICONST: /* ... ==> ..., constant */
480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
481 ICONST(d, iptr->sx.val.i);
482 emit_store_dst(jd, iptr, d);
485 case ICMD_LCONST: /* ... ==> ..., constant */
487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
488 LCONST(d, iptr->sx.val.l);
489 emit_store_dst(jd, iptr, d);
492 case ICMD_FCONST: /* ... ==> ..., constant */
494 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
495 a = dseg_add_float(cd, iptr->sx.val.f);
497 emit_store_dst(jd, iptr, d);
500 case ICMD_DCONST: /* ... ==> ..., constant */
502 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
503 a = dseg_add_double(cd, iptr->sx.val.d);
505 emit_store_dst(jd, iptr, d);
508 case ICMD_ACONST: /* ... ==> ..., constant */
510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
512 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
513 constant_classref *cr = iptr->sx.val.c.ref;;
515 disp = dseg_add_unique_address(cd, cr);
517 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
521 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
523 M_ALD(d, REG_PV, disp);
524 emit_store_dst(jd, iptr, d);
528 /* load/store/copy/move operations ************************************/
530 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
531 case ICMD_ALOAD: /* s1 = local variable */
535 case ICMD_ISTORE: /* ..., value ==> ... */
547 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
552 /* integer operations *************************************************/
554 case ICMD_INEG: /* ..., value ==> ..., - value */
556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559 emit_store_dst(jd, iptr, d);
562 case ICMD_LNEG: /* ..., value ==> ..., - value */
564 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
565 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
566 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
567 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
568 emit_store_dst(jd, iptr, d);
571 case ICMD_I2L: /* ..., value ==> ..., value */
573 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
575 M_INTMOVE(s1, GET_LOW_REG(d));
576 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
577 emit_store_dst(jd, iptr, d);
580 case ICMD_L2I: /* ..., value ==> ..., value */
582 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
585 emit_store_dst(jd, iptr, d);
588 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
601 emit_store_dst(jd, iptr, d);
604 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
609 emit_store_dst(jd, iptr, d);
613 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
617 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
619 emit_store_dst(jd, iptr, d);
622 /* s1.localindex = variable, sx.val.i = constant*/
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
629 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
630 M_IADD_IMM(s1, iptr->sx.val.i, d);
632 ICONST(REG_ITMP2, iptr->sx.val.i);
633 M_IADD(s1, REG_ITMP2, d);
635 /* XXX the old code for ICMD_IINC was as follows:
637 u4 m = iptr->sx.val.i;
641 M_ADDIS(s1, m >> 16, d);
643 M_IADD_IMM(s1, m & 0xffff, d);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
651 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
652 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
654 M_ADDC(s1, s2, GET_LOW_REG(d));
655 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
656 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
657 M_ADDE(s1, s2, GET_HIGH_REG(d));
658 emit_store_dst(jd, iptr, d);
661 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
662 /* sx.val.l = constant */
664 s3 = iptr->sx.val.l & 0xffffffff;
665 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
666 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
667 if ((s3 >= -32768) && (s3 <= 32767))
668 M_ADDIC(s1, s3, GET_LOW_REG(d));
670 ICONST(REG_ITMP2, s3);
671 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
673 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
674 s3 = iptr->sx.val.l >> 32;
676 M_ADDME(s1, GET_HIGH_REG(d));
678 M_ADDZE(s1, GET_HIGH_REG(d));
680 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
681 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
683 emit_store_dst(jd, iptr, d);
686 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
689 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
692 emit_store_dst(jd, iptr, d);
695 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
696 /* sx.val.i = constant */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
701 M_IADD_IMM(s1, -iptr->sx.val.i, d);
703 ICONST(REG_ITMP2, iptr->sx.val.i);
704 M_ISUB(s1, REG_ITMP2, d);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
711 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
712 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
714 M_SUBC(s1, s2, GET_LOW_REG(d));
715 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
716 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
717 M_SUBE(s1, s2, GET_HIGH_REG(d));
718 emit_store_dst(jd, iptr, d);
721 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
722 /* sx.val.l = constant */
724 s3 = (-iptr->sx.val.l) & 0xffffffff;
725 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
727 if ((s3 >= -32768) && (s3 <= 32767)) {
728 M_ADDIC(s1, s3, GET_LOW_REG(d));
730 ICONST(REG_ITMP2, s3);
731 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
733 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
734 s3 = (-iptr->sx.val.l) >> 32;
736 M_ADDME(s1, GET_HIGH_REG(d));
738 M_ADDZE(s1, GET_HIGH_REG(d));
740 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
741 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
743 emit_store_dst(jd, iptr, d);
746 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
751 emit_arithmetic_check(cd, iptr, s2);
752 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
753 M_CMP(REG_ITMP3, s1);
754 M_BNE(3 + (s1 != d));
756 M_BNE(1 + (s1 != d));
760 emit_store_dst(jd, iptr, d);
763 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
768 emit_arithmetic_check(cd, iptr, s2);
769 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
770 M_CMP(REG_ITMP3, s1);
776 M_IDIV(s1, s2, REG_ITMP3);
777 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
778 M_ISUB(s1, REG_ITMP3, d);
779 emit_store_dst(jd, iptr, d);
782 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
783 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
785 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
786 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
788 /* XXX TODO: only do this if arithmetic check is really done! */
789 M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
790 /* XXX could be optimized */
791 emit_arithmetic_check(cd, iptr, REG_ITMP3);
793 bte = iptr->sx.s23.s3.bte;
794 disp = dseg_add_functionptr(cd, bte->fp);
795 M_ALD(REG_ITMP3, REG_PV, disp);
798 M_LNGMOVE(s1, REG_A0_A1_PACKED);
799 M_LNGMOVE(s2, REG_A2_A3_PACKED);
803 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
804 M_LNGMOVE(REG_RESULT_PACKED, d);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
818 /* sx.val.i = constant */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
822 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
823 M_IMUL_IMM(s1, iptr->sx.val.i, d);
825 ICONST(REG_ITMP3, iptr->sx.val.i);
826 M_IMUL(s1, REG_ITMP3, d);
828 emit_store_dst(jd, iptr, d);
831 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
834 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
835 M_SRA_IMM(s1, iptr->sx.val.i, d);
837 emit_store_dst(jd, iptr, d);
840 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
842 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
843 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
844 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
845 M_AND_IMM(s2, 0x1f, REG_ITMP3);
846 M_SLL(s1, REG_ITMP3, d);
847 emit_store_dst(jd, iptr, d);
850 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
851 /* sx.val.i = constant */
853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
856 emit_store_dst(jd, iptr, d);
859 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
862 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
863 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
864 M_AND_IMM(s2, 0x1f, REG_ITMP3);
865 M_SRA(s1, REG_ITMP3, d);
866 emit_store_dst(jd, iptr, d);
869 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
870 /* sx.val.i = constant */
872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
874 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
875 emit_store_dst(jd, iptr, d);
878 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
880 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
881 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
882 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
883 M_AND_IMM(s2, 0x1f, REG_ITMP2);
884 M_SRL(s1, REG_ITMP2, d);
885 emit_store_dst(jd, iptr, d);
888 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
889 /* sx.val.i = constant */
891 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
893 if (iptr->sx.val.i & 0x1f)
894 M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
907 emit_store_dst(jd, iptr, d);
910 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
911 /* sx.val.i = constant */
913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
914 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
915 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
916 M_AND_IMM(s1, iptr->sx.val.i, d);
918 else if (iptr->sx.val.i == 0xffffff) {
919 M_RLWINM(s1, 0, 8, 31, d);
923 ICONST(REG_ITMP3, iptr->sx.val.i);
924 M_AND(s1, REG_ITMP3, d);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
931 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
932 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
933 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
934 M_AND(s1, s2, GET_LOW_REG(d));
935 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
936 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
937 M_AND(s1, s2, GET_HIGH_REG(d));
938 emit_store_dst(jd, iptr, d);
941 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
942 /* sx.val.l = constant */
944 s3 = iptr->sx.val.l & 0xffffffff;
945 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
947 if ((s3 >= 0) && (s3 <= 65535))
948 M_AND_IMM(s1, s3, GET_LOW_REG(d));
950 ICONST(REG_ITMP3, s3);
951 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
953 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
954 s3 = iptr->sx.val.l >> 32;
955 if ((s3 >= 0) && (s3 <= 65535))
956 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
958 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
959 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
961 emit_store_dst(jd, iptr, d);
964 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
965 /* sx.val.i = constant */
967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
968 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
969 M_MOV(s1, REG_ITMP2);
971 M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
972 if (iptr->sx.val.i >= 32768) {
973 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
974 M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
975 M_IADD(s1, REG_ITMP2, REG_ITMP2);
978 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
981 int b=0, m = iptr->sx.val.i;
984 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
986 M_ISUB(s1, REG_ITMP2, d);
987 emit_store_dst(jd, iptr, d);
990 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
992 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
993 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
994 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
996 emit_store_dst(jd, iptr, d);
999 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1000 /* sx.val.i = constant */
1002 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1003 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1004 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1005 M_OR_IMM(s1, iptr->sx.val.i, d);
1007 ICONST(REG_ITMP3, iptr->sx.val.i);
1008 M_OR(s1, REG_ITMP3, d);
1010 emit_store_dst(jd, iptr, d);
1013 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1015 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1016 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1017 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1018 M_OR(s1, s2, GET_LOW_REG(d));
1019 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1020 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1021 M_OR(s1, s2, GET_HIGH_REG(d));
1022 emit_store_dst(jd, iptr, d);
1025 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1026 /* sx.val.l = constant */
1028 s3 = iptr->sx.val.l & 0xffffffff;
1029 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1030 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1031 if ((s3 >= 0) && (s3 <= 65535))
1032 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1034 ICONST(REG_ITMP3, s3);
1035 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1037 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1038 s3 = iptr->sx.val.l >> 32;
1039 if ((s3 >= 0) && (s3 <= 65535))
1040 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1042 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1043 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1045 emit_store_dst(jd, iptr, d);
1048 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1052 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 emit_store_dst(jd, iptr, d);
1057 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1058 /* sx.val.i = constant */
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1062 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1063 M_XOR_IMM(s1, iptr->sx.val.i, d);
1065 ICONST(REG_ITMP3, iptr->sx.val.i);
1066 M_XOR(s1, REG_ITMP3, d);
1068 emit_store_dst(jd, iptr, d);
1071 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1073 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1074 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1075 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1076 M_XOR(s1, s2, GET_LOW_REG(d));
1077 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1078 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1079 M_XOR(s1, s2, GET_HIGH_REG(d));
1080 emit_store_dst(jd, iptr, d);
1083 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1084 /* sx.val.l = constant */
1086 s3 = iptr->sx.val.l & 0xffffffff;
1087 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1088 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1089 if ((s3 >= 0) && (s3 <= 65535))
1090 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1092 ICONST(REG_ITMP3, s3);
1093 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1095 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1096 s3 = iptr->sx.val.l >> 32;
1097 if ((s3 >= 0) && (s3 <= 65535))
1098 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1100 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1101 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1103 emit_store_dst(jd, iptr, d);
1106 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1108 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1109 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1110 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1111 vm_abort("codegen: implement ICMD_LCMP!");
1112 emit_store_dst(jd, iptr, d);
1116 /* floating operations ************************************************/
1118 case ICMD_FNEG: /* ..., value ==> ..., - value */
1120 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1121 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1123 emit_store_dst(jd, iptr, d);
1126 case ICMD_DNEG: /* ..., value ==> ..., - value */
1128 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1129 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1131 emit_store_dst(jd, iptr, d);
1134 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1136 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1137 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1145 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1146 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1147 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1149 emit_store_dst(jd, iptr, d);
1152 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1154 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1155 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1156 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1158 emit_store_dst(jd, iptr, d);
1161 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1163 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1164 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1165 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1167 emit_store_dst(jd, iptr, d);
1170 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1172 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1173 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1174 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1176 emit_store_dst(jd, iptr, d);
1179 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1181 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1182 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1183 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1185 emit_store_dst(jd, iptr, d);
1188 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1190 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1191 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1192 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1194 emit_store_dst(jd, iptr, d);
1197 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1199 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1200 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1201 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1203 emit_store_dst(jd, iptr, d);
1206 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1209 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1210 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1212 disp = dseg_add_float(cd, 0.0);
1213 M_FLD(REG_FTMP2, REG_PV, disp);
1214 M_FCMPU(s1, REG_FTMP2);
1216 disp = dseg_add_unique_s4(cd, 0);
1217 M_CVTDL_C(s1, REG_FTMP1);
1218 M_LDA(REG_ITMP1, REG_PV, disp);
1219 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1220 M_ILD(d, REG_PV, disp);
1221 emit_store_dst(jd, iptr, d);
1224 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1226 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1227 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1229 emit_store_dst(jd, iptr, d);
1232 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1234 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1235 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1237 emit_store_dst(jd, iptr, d);
1240 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1241 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1243 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1244 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1247 M_IADD_IMM(REG_ZERO, -1, d);
1250 M_IADD_IMM(REG_ZERO, 0, d);
1252 M_IADD_IMM(REG_ZERO, 1, d);
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1257 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1259 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1260 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1261 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1263 M_IADD_IMM(REG_ZERO, 1, d);
1266 M_IADD_IMM(REG_ZERO, 0, d);
1268 M_IADD_IMM(REG_ZERO, -1, d);
1269 emit_store_dst(jd, iptr, d);
1273 /* memory operations **************************************************/
1275 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1277 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1279 /* implicit null-pointer check */
1280 M_ILD(d, s1, OFFSET(java_array_t, size));
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1286 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1287 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1288 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1289 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1290 M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1291 /* implicit null-pointer check */
1292 M_LBZX(d, s1, REG_ITMP2);
1294 emit_store_dst(jd, iptr, d);
1297 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1300 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1301 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1302 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1303 M_SLL_IMM(s2, 1, REG_ITMP2);
1304 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1305 /* implicit null-pointer check */
1306 M_LHZX(d, s1, REG_ITMP2);
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1313 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1314 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1315 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1316 M_SLL_IMM(s2, 1, REG_ITMP2);
1317 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1318 /* implicit null-pointer check */
1319 M_LHAX(d, s1, REG_ITMP2);
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1326 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1327 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1328 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1329 M_SLL_IMM(s2, 2, REG_ITMP2);
1330 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1331 /* implicit null-pointer check */
1332 M_LWZX(d, s1, REG_ITMP2);
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1341 /* implicit null-pointer check */
1342 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1343 M_SLL_IMM(s2, 3, REG_ITMP2);
1344 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1345 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray_t, data[0]));
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1354 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1355 M_SLL_IMM(s2, 2, REG_ITMP2);
1356 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1357 /* implicit null-pointer check */
1358 M_LFSX(d, s1, REG_ITMP2);
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1364 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1365 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1367 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1368 M_SLL_IMM(s2, 3, REG_ITMP2);
1369 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1370 /* implicit null-pointer check */
1371 M_LFDX(d, s1, REG_ITMP2);
1372 emit_store_dst(jd, iptr, d);
1375 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1377 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1378 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1379 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1380 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1381 M_SLL_IMM(s2, 2, REG_ITMP2);
1382 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1383 /* implicit null-pointer check */
1384 M_LWZX(d, s1, REG_ITMP2);
1385 emit_store_dst(jd, iptr, d);
1389 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1391 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1392 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1393 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1394 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1395 M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1396 /* implicit null-pointer check */
1397 M_STBX(s3, s1, REG_ITMP2);
1400 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1404 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1405 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1406 M_SLL_IMM(s2, 1, REG_ITMP2);
1407 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1408 /* implicit null-pointer check */
1409 M_STHX(s3, s1, REG_ITMP2);
1412 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1414 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1415 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1416 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1417 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1418 M_SLL_IMM(s2, 1, REG_ITMP2);
1419 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1420 /* implicit null-pointer check */
1421 M_STHX(s3, s1, REG_ITMP2);
1424 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1427 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1428 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1429 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1430 M_SLL_IMM(s2, 2, REG_ITMP2);
1431 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1432 /* implicit null-pointer check */
1433 M_STWX(s3, s1, REG_ITMP2);
1436 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1439 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1440 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1441 s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1442 M_SLL_IMM(s2, 3, REG_ITMP2);
1443 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray_t, data[0]), REG_ITMP2);
1444 /* implicit null-pointer check */
1445 M_STWX(s3, s1, REG_ITMP2);
1446 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1447 s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1448 M_STWX(s3, s1, REG_ITMP2);
1451 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1453 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1454 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1455 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1456 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1457 M_SLL_IMM(s2, 2, REG_ITMP2);
1458 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1459 /* implicit null-pointer check */
1460 M_STFSX(s3, s1, REG_ITMP2);
1463 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1468 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1469 M_SLL_IMM(s2, 3, REG_ITMP2);
1470 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1471 /* implicit null-pointer check */
1472 M_STFDX(s3, s1, REG_ITMP2);
1475 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1477 s1 = emit_load_s1(jd, iptr, REG_A0);
1478 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1479 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1480 s3 = emit_load_s3(jd, iptr, REG_A1);
1482 /* XXX what if array is NULL */
1483 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1484 M_ALD(REG_ITMP3, REG_PV, disp);
1487 M_INTMOVE(s1, REG_A0);
1488 M_INTMOVE(s3, REG_A1);
1491 emit_arraystore_check(cd, iptr);
1493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1494 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1495 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1496 M_SLL_IMM(s2, 2, REG_ITMP2);
1497 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1498 /* implicit null-pointer check */
1499 M_STWX(s3, s1, REG_ITMP2);
1503 case ICMD_GETSTATIC: /* ... ==> ..., value */
1505 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1506 uf = iptr->sx.s23.s3.uf;
1507 fieldtype = uf->fieldref->parseddesc.fd->type;
1508 disp = dseg_add_unique_address(cd, uf);
1510 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1513 fi = iptr->sx.s23.s3.fmiref->p.field;
1514 fieldtype = fi->type;
1515 disp = dseg_add_address(cd, fi->value);
1517 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1518 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1522 M_ALD(REG_ITMP1, REG_PV, disp);
1523 switch (fieldtype) {
1525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1526 M_ILD_INTERN(d, REG_ITMP1, 0);
1529 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1530 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1531 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1535 M_ALD_INTERN(d, REG_ITMP1, 0);
1538 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1539 M_FLD_INTERN(d, REG_ITMP1, 0);
1542 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1543 M_DLD_INTERN(d, REG_ITMP1, 0);
1546 emit_store_dst(jd, iptr, d);
1549 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1551 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1552 uf = iptr->sx.s23.s3.uf;
1553 fieldtype = uf->fieldref->parseddesc.fd->type;
1554 disp = dseg_add_unique_address(cd, uf);
1556 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1559 fi = iptr->sx.s23.s3.fmiref->p.field;
1560 fieldtype = fi->type;
1561 disp = dseg_add_address(cd, fi->value);
1563 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1564 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1568 M_ALD(REG_ITMP1, REG_PV, disp);
1569 switch (fieldtype) {
1571 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1572 M_IST_INTERN(s1, REG_ITMP1, 0);
1575 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1576 M_LST_INTERN(s1, REG_ITMP1, 0);
1579 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1580 M_AST_INTERN(s1, REG_ITMP1, 0);
1583 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1584 M_FST_INTERN(s1, REG_ITMP1, 0);
1587 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1588 M_DST_INTERN(s1, REG_ITMP1, 0);
1594 case ICMD_GETFIELD: /* ... ==> ..., value */
1596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1598 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1599 uf = iptr->sx.s23.s3.uf;
1600 fieldtype = uf->fieldref->parseddesc.fd->type;
1603 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1606 fi = iptr->sx.s23.s3.fmiref->p.field;
1607 fieldtype = fi->type;
1611 /* implicit null-pointer check */
1612 switch (fieldtype) {
1614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1619 if (GET_HIGH_REG(d) == s1) {
1620 M_ILD(GET_LOW_REG(d), s1, disp + 4);
1621 M_ILD(GET_HIGH_REG(d), s1, disp);
1624 M_ILD(GET_HIGH_REG(d), s1, disp);
1625 M_ILD(GET_LOW_REG(d), s1, disp + 4);
1629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1633 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1637 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1641 emit_store_dst(jd, iptr, d);
1644 case ICMD_PUTFIELD: /* ..., value ==> ... */
1646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1648 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1649 uf = iptr->sx.s23.s3.uf;
1650 fieldtype = uf->fieldref->parseddesc.fd->type;
1654 fi = iptr->sx.s23.s3.fmiref->p.field;
1655 fieldtype = fi->type;
1659 if (IS_INT_LNG_TYPE(fieldtype)) {
1660 if (IS_2_WORD_TYPE(fieldtype))
1661 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1663 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1666 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1668 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1669 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1671 /* implicit null-pointer check */
1672 switch (fieldtype) {
1674 M_IST(s2, s1, disp);
1677 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
1678 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
1681 M_AST(s2, s1, disp);
1684 M_FST(s2, s1, disp);
1687 M_DST(s2, s1, disp);
1693 /* branch operations **************************************************/
1695 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1698 M_INTMOVE(s1, REG_ITMP1_XPTR);
1700 #ifdef ENABLE_VERIFIER
1701 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1702 unresolved_class *uc = iptr->sx.s23.s2.uc;
1704 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1706 #endif /* ENABLE_VERIFIER */
1708 disp = dseg_add_functionptr(cd, asm_handle_exception);
1709 M_ALD(REG_ITMP2, REG_PV, disp);
1712 if (code_is_leafmethod(code))
1713 M_MFLR(REG_ITMP3); /* save LR */
1715 M_BL(0); /* get current PC */
1716 M_MFLR(REG_ITMP2_XPC);
1718 if (code_is_leafmethod(code))
1719 M_MTLR(REG_ITMP3); /* restore LR */
1721 M_RTS; /* jump to CTR */
1725 case ICMD_GOTO: /* ... ==> ... */
1726 case ICMD_RET: /* ... ==> ... */
1728 emit_br(cd, iptr->dst.block);
1732 case ICMD_JSR: /* ... ==> ... */
1734 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1738 case ICMD_IFNULL: /* ..., value ==> ... */
1739 case ICMD_IFNONNULL:
1741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1751 case ICMD_IFEQ: /* ..., value ==> ... */
1753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1754 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1755 M_CMPI(s1, iptr->sx.val.i);
1757 ICONST(REG_ITMP2, iptr->sx.val.i);
1758 M_CMP(s1, REG_ITMP2);
1760 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1764 case ICMD_IF_LEQ: /* ..., value ==> ... */
1766 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1767 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1768 if (iptr->sx.val.l == 0) {
1769 M_OR_TST(s1, s2, REG_ITMP3);
1771 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1772 M_XOR_IMM(s2, 0, REG_ITMP2);
1773 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1774 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1777 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1778 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1779 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1780 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1781 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1783 emit_beq(cd, iptr->dst.block);
1786 case ICMD_IF_LLT: /* ..., value ==> ... */
1788 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1789 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1790 if (iptr->sx.val.l == 0) {
1791 /* if high word is less than zero, the whole long is too */
1793 emit_blt(cd, iptr->dst.block);
1795 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1797 emit_blt(cd, iptr->dst.block);
1798 emit_label_bgt(cd, BRANCH_LABEL_1);
1799 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1800 emit_blt(cd, iptr->dst.block);
1801 emit_label(cd, BRANCH_LABEL_1);
1804 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1805 M_CMP(s2, REG_ITMP3);
1806 emit_blt(cd, iptr->dst.block);
1807 emit_label_bgt(cd, BRANCH_LABEL_1);
1808 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1809 M_CMPU(s1, REG_ITMP3);
1810 emit_blt(cd, iptr->dst.block);
1811 emit_label(cd, BRANCH_LABEL_1);
1815 case ICMD_IF_LLE: /* ..., value ==> ... */
1817 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1818 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1819 /* if (iptr->sx.val.l == 0) { */
1820 /* M_OR(s1, s2, REG_ITMP3); */
1821 /* M_CMPI(REG_ITMP3, 0); */
1824 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1826 emit_blt(cd, iptr->dst.block);
1827 emit_label_bgt(cd, BRANCH_LABEL_1);
1828 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1831 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1832 M_CMP(s2, REG_ITMP3);
1833 emit_blt(cd, iptr->dst.block);
1834 emit_label_bgt(cd, BRANCH_LABEL_1);
1835 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1836 M_CMPU(s1, REG_ITMP3);
1838 emit_ble(cd, iptr->dst.block);
1839 emit_label(cd, BRANCH_LABEL_1);
1842 case ICMD_IF_LNE: /* ..., value ==> ... */
1844 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1845 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1846 if (iptr->sx.val.l == 0) {
1847 M_OR_TST(s1, s2, REG_ITMP3);
1849 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1850 M_XOR_IMM(s2, 0, REG_ITMP2);
1851 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1852 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1855 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1856 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1857 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1858 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1859 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1861 emit_bne(cd, iptr->dst.block);
1864 case ICMD_IF_LGT: /* ..., value ==> ... */
1866 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1867 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1868 /* if (iptr->sx.val.l == 0) { */
1869 /* M_OR(s1, s2, REG_ITMP3); */
1870 /* M_CMPI(REG_ITMP3, 0); */
1873 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1875 emit_bgt(cd, iptr->dst.block);
1876 emit_label_blt(cd, BRANCH_LABEL_1);
1877 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1880 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1881 M_CMP(s2, REG_ITMP3);
1882 emit_bgt(cd, iptr->dst.block);
1883 emit_label_blt(cd, BRANCH_LABEL_1);
1884 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1885 M_CMPU(s1, REG_ITMP3);
1887 emit_bgt(cd, iptr->dst.block);
1888 emit_label(cd, BRANCH_LABEL_1);
1891 case ICMD_IF_LGE: /* ..., value ==> ... */
1893 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1894 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1895 if (iptr->sx.val.l == 0) {
1896 /* if high word is greater equal zero, the whole long is too */
1898 emit_bge(cd, iptr->dst.block);
1900 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1902 emit_bgt(cd, iptr->dst.block);
1903 emit_label_blt(cd, BRANCH_LABEL_1);
1904 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1905 emit_bge(cd, iptr->dst.block);
1906 emit_label(cd, BRANCH_LABEL_1);
1909 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1910 M_CMP(s2, REG_ITMP3);
1911 emit_bgt(cd, iptr->dst.block);
1912 emit_label_blt(cd, BRANCH_LABEL_1);
1913 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1914 M_CMPU(s1, REG_ITMP3);
1915 emit_bge(cd, iptr->dst.block);
1916 emit_label(cd, BRANCH_LABEL_1);
1920 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1921 case ICMD_IF_ICMPNE:
1922 case ICMD_IF_ICMPLT:
1923 case ICMD_IF_ICMPGT:
1924 case ICMD_IF_ICMPLE:
1925 case ICMD_IF_ICMPGE:
1927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1928 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1930 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1933 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1934 case ICMD_IF_ACMPNE:
1936 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1937 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1939 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1942 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1944 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1945 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1947 emit_label_bne(cd, BRANCH_LABEL_1);
1948 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1949 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1951 emit_beq(cd, iptr->dst.block);
1952 emit_label(cd, BRANCH_LABEL_1);
1955 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1957 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1958 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1960 emit_bne(cd, iptr->dst.block);
1961 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1962 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1964 emit_bne(cd, iptr->dst.block);
1967 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1969 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1970 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1972 emit_blt(cd, iptr->dst.block);
1973 emit_label_bgt(cd, BRANCH_LABEL_1);
1974 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1975 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1977 emit_blt(cd, iptr->dst.block);
1978 emit_label(cd, BRANCH_LABEL_1);
1981 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1983 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1984 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1986 emit_bgt(cd, iptr->dst.block);
1987 emit_label_blt(cd, BRANCH_LABEL_1);
1988 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1989 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1991 emit_bgt(cd, iptr->dst.block);
1992 emit_label(cd, BRANCH_LABEL_1);
1995 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1997 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1998 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2000 emit_blt(cd, iptr->dst.block);
2001 emit_label_bgt(cd, BRANCH_LABEL_1);
2002 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2003 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2005 emit_ble(cd, iptr->dst.block);
2006 emit_label(cd, BRANCH_LABEL_1);
2009 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2011 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2012 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2014 emit_bgt(cd, iptr->dst.block);
2015 emit_label_blt(cd, BRANCH_LABEL_1);
2016 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2017 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2019 emit_bge(cd, iptr->dst.block);
2020 emit_label(cd, BRANCH_LABEL_1);
2023 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2025 REPLACEMENT_POINT_RETURN(cd, iptr);
2026 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2027 M_INTMOVE(s1, REG_RESULT);
2028 goto nowperformreturn;
2030 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2032 REPLACEMENT_POINT_RETURN(cd, iptr);
2033 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2034 M_INTMOVE(s1, REG_RESULT);
2036 #ifdef ENABLE_VERIFIER
2037 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2038 unresolved_class *uc = iptr->sx.s23.s2.uc;
2040 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2042 #endif /* ENABLE_VERIFIER */
2043 goto nowperformreturn;
2045 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2047 REPLACEMENT_POINT_RETURN(cd, iptr);
2048 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2049 M_LNGMOVE(s1, REG_RESULT_PACKED);
2050 goto nowperformreturn;
2052 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2055 REPLACEMENT_POINT_RETURN(cd, iptr);
2056 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2057 M_FLTMOVE(s1, REG_FRESULT);
2058 goto nowperformreturn;
2060 case ICMD_RETURN: /* ... ==> ... */
2062 REPLACEMENT_POINT_RETURN(cd, iptr);
2068 p = cd->stackframesize;
2070 /* call trace function */
2072 emit_verbosecall_exit(jd);
2074 #if defined(ENABLE_THREADS)
2075 if (checksync && code_is_synchronized(code)) {
2076 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2077 M_ALD(REG_ITMP3, REG_PV, disp);
2080 /* we need to save the proper return value */
2082 switch (iptr->opc) {
2084 M_IST(REG_RESULT2, REG_SP, rd->memuse * 8 + 8);
2088 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 4);
2092 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 4);
2096 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2099 /* and now restore the proper return value */
2101 switch (iptr->opc) {
2103 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 8 + 8);
2107 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 4);
2111 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 4);
2117 /* restore return address */
2119 if (!code_is_leafmethod(code)) {
2120 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2121 may have a displacement overflow. */
2123 M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
2127 /* restore saved registers */
2129 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2130 p--; M_ILD(rd->savintregs[i], REG_SP, p * 8);
2132 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2133 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2136 /* deallocate stack */
2138 if (cd->stackframesize)
2139 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2147 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2150 branch_target_t *table;
2152 table = iptr->dst.table;
2154 l = iptr->sx.s23.s2.tablelow;
2155 i = iptr->sx.s23.s3.tablehigh;
2157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2159 M_INTMOVE(s1, REG_ITMP1);
2160 else if (l <= 32768)
2161 M_LDA(REG_ITMP1, s1, -l);
2163 ICONST(REG_ITMP2, l);
2164 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2171 M_CMPUI(REG_ITMP1, i - 1);
2172 emit_bgt(cd, table[0].block);
2174 /* build jump table top down and use address of lowest entry */
2179 dseg_add_target(cd, table->block);
2183 /* length of dataseg after last dseg_add_target is used by load */
2185 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2186 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2187 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2195 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2198 lookup_target_t *lookup;
2200 lookup = iptr->dst.lookup;
2202 i = iptr->sx.s23.s2.lookupcount;
2204 MCODECHECK((i<<2)+8);
2205 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2208 if ((lookup->value >= -32768) && (lookup->value <= 32767)) {
2209 M_CMPI(s1, lookup->value);
2212 disp = dseg_add_s4(cd, lookup->value);
2213 M_ILD(REG_ITMP2, REG_PV, disp);
2214 M_CMP(s1, REG_ITMP2);
2216 emit_beq(cd, lookup->target.block);
2220 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2226 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2228 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2230 bte = iptr->sx.s23.s3.bte;
2234 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2236 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2237 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2238 case ICMD_INVOKEINTERFACE:
2240 REPLACEMENT_POINT_INVOKE(cd, iptr);
2242 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2244 um = iptr->sx.s23.s3.um;
2245 md = um->methodref->parseddesc.md;
2248 lm = iptr->sx.s23.s3.fmiref->p.method;
2250 md = lm->parseddesc;
2254 s3 = md->paramcount;
2256 MCODECHECK((s3 << 1) + 64);
2258 /* copy arguments to registers or stack location */
2260 for (s3 = s3 - 1; s3 >= 0; s3--) {
2261 var = VAR(iptr->sx.s23.s2.args[s3]);
2262 d = md->params[s3].regoff;
2264 /* Already Preallocated? */
2265 if (var->flags & PREALLOC)
2268 if (IS_INT_LNG_TYPE(var->type)) {
2269 if (!md->params[s3].inmemory) {
2270 if (IS_2_WORD_TYPE(var->type)) {
2271 s1 = emit_load(jd, iptr, var, d);
2275 s1 = emit_load(jd, iptr, var, d);
2280 if (IS_2_WORD_TYPE(var->type)) {
2281 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2282 M_LST(s1, REG_SP, d);
2285 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2286 M_IST(s1, REG_SP, d);
2291 if (!md->params[s3].inmemory) {
2292 s1 = emit_load(jd, iptr, var, d);
2296 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2297 M_DST(s1, REG_SP, d);
2302 switch (iptr->opc) {
2304 if (bte->stub == NULL)
2305 disp = dseg_add_functionptr(cd, bte->fp);
2307 disp = dseg_add_functionptr(cd, bte->stub);
2309 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
2311 /* generate the actual call */
2315 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2316 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2317 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2319 M_LDA(REG_PV, REG_ITMP1, -disp);
2322 case ICMD_INVOKESPECIAL:
2323 emit_nullpointer_check(cd, iptr, REG_A0);
2326 case ICMD_INVOKESTATIC:
2328 disp = dseg_add_unique_address(cd, um);
2330 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2334 disp = dseg_add_address(cd, lm->stubroutine);
2336 M_ALD(REG_PV, REG_PV, disp);
2338 /* generate the actual call */
2342 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2343 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2345 M_LDA(REG_PV, REG_ITMP1, -disp);
2348 case ICMD_INVOKEVIRTUAL:
2350 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2355 s1 = OFFSET(vftbl_t, table[0]) +
2356 sizeof(methodptr) * lm->vftblindex;
2359 /* implicit null-pointer check */
2360 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2361 M_ALD(REG_PV, REG_METHODPTR, s1);
2363 /* generate the actual call */
2367 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2368 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2370 M_LDA(REG_PV, REG_ITMP1, -disp);
2373 case ICMD_INVOKEINTERFACE:
2375 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2381 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2382 sizeof(methodptr*) * lm->class->index;
2384 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2387 /* implicit null-pointer check */
2388 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2389 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2390 M_ALD(REG_PV, REG_METHODPTR, s2);
2392 /* generate the actual call */
2396 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2397 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2399 M_LDA(REG_PV, REG_ITMP1, -disp);
2403 /* store return value */
2405 d = md->returntype.type;
2407 if (d != TYPE_VOID) {
2408 if (IS_INT_LNG_TYPE(d)) {
2409 if (IS_2_WORD_TYPE(d)) {
2410 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2411 M_LNGMOVE(REG_RESULT_PACKED, s1);
2414 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2415 M_INTMOVE(REG_RESULT, s1);
2419 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2420 M_FLTMOVE(REG_FRESULT, s1);
2422 emit_store_dst(jd, iptr, s1);
2427 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2429 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2430 /* object type cast-check */
2435 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2440 super = iptr->sx.s23.s3.c.cls;
2441 superindex = super->index;
2444 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2445 CODEGEN_CRITICAL_SECTION_NEW;
2447 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2449 /* if class is not resolved, check which code to call */
2451 if (super == NULL) {
2453 emit_label_beq(cd, BRANCH_LABEL_1);
2455 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2457 patcher_add_patch_ref(jd,
2458 PATCHER_resolve_classref_to_flags,
2459 iptr->sx.s23.s3.c.ref,
2462 M_ILD(REG_ITMP2, REG_PV, disp);
2463 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2464 emit_label_beq(cd, BRANCH_LABEL_2);
2467 /* interface checkcast code */
2469 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2470 if (super == NULL) {
2471 patcher_add_patch_ref(jd,
2472 PATCHER_checkcast_interface,
2473 iptr->sx.s23.s3.c.ref,
2478 emit_label_beq(cd, BRANCH_LABEL_3);
2481 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2482 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2483 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2484 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2486 M_ALD(REG_ITMP3, REG_ITMP2,
2487 OFFSET(vftbl_t, interfacetable[0]) -
2488 superindex * sizeof(methodptr*));
2490 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2493 emit_label_br(cd, BRANCH_LABEL_4);
2495 emit_label(cd, BRANCH_LABEL_3);
2498 /* class checkcast code */
2500 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2501 if (super == NULL) {
2502 emit_label(cd, BRANCH_LABEL_2);
2504 disp = dseg_add_unique_address(cd, NULL);
2506 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2507 iptr->sx.s23.s3.c.ref,
2511 disp = dseg_add_address(cd, super->vftbl);
2514 emit_label_beq(cd, BRANCH_LABEL_5);
2517 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2519 CODEGEN_CRITICAL_SECTION_START;
2521 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2522 M_ALD(REG_ITMP2, REG_PV, disp);
2523 if (s1 != REG_ITMP1) {
2524 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
2525 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2527 CODEGEN_CRITICAL_SECTION_END;
2529 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
2532 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2533 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2534 M_ALD(REG_ITMP2, REG_PV, disp);
2535 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2537 CODEGEN_CRITICAL_SECTION_END;
2539 M_CMPU(REG_ITMP3, REG_ITMP2);
2540 emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
2543 emit_label(cd, BRANCH_LABEL_5);
2546 if (super == NULL) {
2547 emit_label(cd, BRANCH_LABEL_1);
2548 emit_label(cd, BRANCH_LABEL_4);
2551 d = codegen_reg_of_dst(jd, iptr, s1);
2554 /* array type cast-check */
2556 s1 = emit_load_s1(jd, iptr, REG_A0);
2557 M_INTMOVE(s1, REG_A0);
2559 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2560 disp = dseg_add_unique_address(cd, NULL);
2562 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2563 iptr->sx.s23.s3.c.ref,
2567 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2569 M_ALD(REG_A1, REG_PV, disp);
2570 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2571 M_ALD(REG_ITMP2, REG_PV, disp);
2575 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2578 d = codegen_reg_of_dst(jd, iptr, s1);
2581 emit_store_dst(jd, iptr, d);
2584 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2590 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2595 super = iptr->sx.s23.s3.c.cls;
2596 superindex = super->index;
2599 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2600 CODEGEN_CRITICAL_SECTION_NEW;
2602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2606 M_MOV(s1, REG_ITMP1);
2612 /* if class is not resolved, check which code to call */
2614 if (super == NULL) {
2616 emit_label_beq(cd, BRANCH_LABEL_1);
2618 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2620 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2621 iptr->sx.s23.s3.c.ref, disp);
2623 M_ILD(REG_ITMP3, REG_PV, disp);
2624 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2625 emit_label_beq(cd, BRANCH_LABEL_2);
2628 /* interface instanceof code */
2630 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2631 if (super == NULL) {
2632 patcher_add_patch_ref(jd,
2633 PATCHER_instanceof_interface,
2634 iptr->sx.s23.s3.c.ref, 0);
2638 emit_label_beq(cd, BRANCH_LABEL_3);
2641 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2642 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2643 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2645 M_ALD(REG_ITMP1, REG_ITMP1,
2646 OFFSET(vftbl_t, interfacetable[0]) -
2647 superindex * sizeof(methodptr*));
2650 M_IADD_IMM(REG_ZERO, 1, d);
2653 emit_label_br(cd, BRANCH_LABEL_4);
2655 emit_label(cd, BRANCH_LABEL_3);
2658 /* class instanceof code */
2660 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2661 if (super == NULL) {
2662 emit_label(cd, BRANCH_LABEL_2);
2664 disp = dseg_add_unique_address(cd, NULL);
2666 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2667 iptr->sx.s23.s3.c.ref,
2671 disp = dseg_add_address(cd, super->vftbl);
2674 emit_label_beq(cd, BRANCH_LABEL_5);
2677 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2678 M_ALD(REG_ITMP2, REG_PV, disp);
2680 CODEGEN_CRITICAL_SECTION_START;
2682 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2683 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2684 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2686 CODEGEN_CRITICAL_SECTION_END;
2688 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2689 M_CMPU(REG_ITMP1, REG_ITMP2);
2692 M_IADD_IMM(REG_ZERO, 1, d);
2695 emit_label(cd, BRANCH_LABEL_5);
2698 if (super == NULL) {
2699 emit_label(cd, BRANCH_LABEL_1);
2700 emit_label(cd, BRANCH_LABEL_4);
2703 emit_store_dst(jd, iptr, d);
2707 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2709 /* check for negative sizes and copy sizes to stack if necessary */
2711 MCODECHECK((iptr->s1.argcount << 1) + 64);
2713 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2714 var = VAR(iptr->sx.s23.s2.args[s1]);
2716 /* copy SAVEDVAR sizes to stack */
2718 /* Already Preallocated? */
2719 if (!(var->flags & PREALLOC)) {
2720 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2721 #if defined(__DARWIN__)
2722 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
2724 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
2729 /* a0 = dimension count */
2731 ICONST(REG_A0, iptr->s1.argcount);
2733 /* is patcher function set? */
2735 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2736 disp = dseg_add_unique_address(cd, NULL);
2738 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2739 iptr->sx.s23.s3.c.ref, disp);
2742 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2744 /* a1 = arraydescriptor */
2746 M_ALD(REG_A1, REG_PV, disp);
2748 /* a2 = pointer to dimensions = stack pointer */
2750 #if defined(__DARWIN__)
2751 M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 4);
2753 M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 4);
2756 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2757 M_ALD(REG_ITMP3, REG_PV, disp);
2761 /* check for exception before result assignment */
2763 emit_exception_check(cd, iptr);
2765 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2766 M_INTMOVE(REG_RESULT, d);
2767 emit_store_dst(jd, iptr, d);
2771 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2776 } /* for instruction */
2778 } /* if (bptr -> flags >= BBREACHED) */
2779 } /* for basic block */
2781 dseg_createlinenumbertable(cd);
2783 /* generate traps */
2785 emit_patcher_traps(jd);
2787 /* everything's ok */
2793 /* codegen_emit_stub_native ****************************************************
2795 Emits a stub routine which calls a native method.
2797 *******************************************************************************/
2799 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2805 s4 i, j; /* count variables */
2810 /* get required compiler data */
2816 /* set some variables */
2820 /* calculate stackframe size */
2822 cd->stackframesize =
2823 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2824 sizeof(localref_table) / SIZEOF_VOID_P +
2825 4 + /* 4 stackframeinfo arguments (darwin) */
2829 /* keep stack 16-byte aligned */
2831 ALIGN_2(cd->stackframesize);
2833 /* create method header */
2835 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2836 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2837 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2838 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2839 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2840 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2841 (void) dseg_addlinenumbertablesize(cd);
2842 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2847 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
2848 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
2850 #if defined(ENABLE_GC_CACAO)
2851 /* Save callee saved integer registers in stackframeinfo (GC may
2852 need to recover them during a collection). */
2854 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2855 OFFSET(stackframeinfo_t, intregs);
2857 for (i = 0; i < INT_SAV_CNT; i++)
2858 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
2861 /* save integer and float argument registers */
2863 for (i = 0; i < md->paramcount; i++) {
2864 if (!md->params[i].inmemory) {
2865 s1 = md->params[i].regoff;
2867 switch (md->paramtypes[i].type) {
2870 M_IST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2873 M_LST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2877 M_DST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2883 /* create native stack info */
2885 M_MOV(REG_SP, REG_A0);
2886 M_MOV(REG_PV, REG_A1);
2887 disp = dseg_add_functionptr(cd, codegen_start_native_call);
2888 M_ALD(REG_ITMP1, REG_PV, disp);
2892 /* remember class argument */
2894 if (m->flags & ACC_STATIC)
2895 M_MOV(REG_RESULT, REG_ITMP3);
2897 /* restore integer and float argument registers */
2899 for (i = 0; i < md->paramcount; i++) {
2900 if (!md->params[i].inmemory) {
2901 s1 = md->params[i].regoff;
2903 switch (md->paramtypes[i].type) {
2906 M_ILD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2909 M_LLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2913 M_DLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2919 /* copy or spill arguments to new locations */
2921 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2922 t = md->paramtypes[i].type;
2924 if (IS_INT_LNG_TYPE(t)) {
2925 if (!md->params[i].inmemory) {
2926 s1 = md->params[i].regoff;
2927 s2 = nmd->params[j].regoff;
2929 if (!nmd->params[j].inmemory) {
2930 if (IS_2_WORD_TYPE(t))
2936 if (IS_2_WORD_TYPE(t))
2937 M_LST(s1, REG_SP, s2);
2939 M_IST(s1, REG_SP, s2);
2943 s1 = md->params[i].regoff + cd->stackframesize * 8;
2944 s2 = nmd->params[j].regoff;
2946 M_ILD(REG_ITMP1, REG_SP, s1);
2947 if (IS_2_WORD_TYPE(t))
2948 M_ILD(REG_ITMP2, REG_SP, s1 + 4);
2950 M_IST(REG_ITMP1, REG_SP, s2);
2951 if (IS_2_WORD_TYPE(t))
2952 M_IST(REG_ITMP2, REG_SP, s2 + 4);
2956 /* We only copy spilled float arguments, as the float
2957 argument registers keep unchanged. */
2959 if (md->params[i].inmemory) {
2960 s1 = md->params[i].regoff + cd->stackframesize * 8;
2961 s2 = nmd->params[j].regoff;
2963 M_DLD(REG_FTMP1, REG_SP, s1);
2965 if (IS_2_WORD_TYPE(t))
2966 M_DST(REG_FTMP1, REG_SP, s2);
2968 M_FST(REG_FTMP1, REG_SP, s2);
2973 /* Handle native Java methods. */
2975 if (m->flags & ACC_NATIVE) {
2976 /* put class into second argument register */
2978 if (m->flags & ACC_STATIC)
2979 M_MOV(REG_ITMP3, REG_A1);
2981 /* put env into first argument register */
2983 disp = dseg_add_address(cd, _Jv_env);
2984 M_ALD(REG_A0, REG_PV, disp);
2987 /* Call the native function. */
2989 disp = dseg_add_functionptr(cd, f);
2990 M_ALD(REG_ITMP3, REG_PV, disp);
2994 /* save return value */
2996 switch (md->returntype.type) {
2999 M_IST(REG_RESULT, REG_SP, LA_SIZE + 2 * 4);
3002 M_LST(REG_RESULT_PACKED, REG_SP, LA_SIZE + 2 * 4);
3006 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 2 * 4);
3012 /* remove native stackframe info */
3014 M_MOV(REG_SP, REG_A0);
3015 M_MOV(REG_PV, REG_A1);
3016 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3017 M_ALD(REG_ITMP1, REG_PV, disp);
3020 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3022 /* restore return value */
3024 switch (md->returntype.type) {
3027 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 2 * 4);
3030 M_LLD(REG_RESULT_PACKED, REG_SP, LA_SIZE + 2 * 4);
3034 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 2 * 4);
3040 #if defined(ENABLE_GC_CACAO)
3041 /* Restore callee saved integer registers from stackframeinfo (GC
3042 might have modified them during a collection). */
3044 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3045 OFFSET(stackframeinfo_t, intregs);
3047 for (i = 0; i < INT_SAV_CNT; i++)
3048 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3051 M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
3052 M_MTLR(REG_ITMP2_XPC);
3053 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe */
3055 /* check for exception */
3057 M_TST(REG_ITMP1_XPTR);
3058 M_BNE(1); /* if no exception then return */
3062 /* handle exception */
3064 M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3066 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3067 M_ALD(REG_ITMP3, REG_PV, disp);
3074 * These are local overrides for various environment variables in Emacs.
3075 * Please do not remove this and leave it at the end of the file, where
3076 * Emacs will automagically detect them.
3077 * ---------------------------------------------------------------------
3080 * indent-tabs-mode: t
3084 * vim:noexpandtab:sw=4:ts=4: