1 /* src/vm/jit/powerpc/codegen.c - machine code generator for 32-bit PowerPC
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
36 #include "vm/jit/powerpc/arch.h"
37 #include "vm/jit/powerpc/codegen.h"
39 #include "mm/memory.h"
41 #include "native/localref.h"
42 #include "native/native.h"
44 #include "threads/lock-common.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49 #include "vm/stringlocal.h"
52 #include "vm/jit/abi.h"
53 #include "vm/jit/abi-asm.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen-common.h"
56 #include "vm/jit/dseg.h"
57 #include "vm/jit/emit-common.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/linenumbertable.h"
60 #include "vm/jit/methodheader.h"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/patcher-common.h"
63 #include "vm/jit/reg.h"
64 #include "vm/jit/replace.h"
65 #include "vm/jit/stacktrace.hpp"
66 #include "vm/jit/trap.h"
68 #if defined(ENABLE_LSRA)
69 # include "vm/jit/allocator/lsra.h"
72 #include "vmcore/loader.h"
73 #include "vmcore/options.h"
76 /* codegen *********************************************************************
78 Generates machine code.
80 *******************************************************************************/
82 bool codegen_emit(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
93 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
94 unresolved_method *um;
95 builtintable_entry *bte;
103 /* get required compiler data */
110 /* prevent compiler warnings */
125 /* space to save used callee saved registers */
127 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
128 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
130 cd->stackframesize = rd->memuse + savedregs_num;
132 #if defined(ENABLE_THREADS)
133 /* Space to save argument of monitor_enter and Return Values to
134 survive monitor_exit. The stack position for the argument can
135 not be shared with place to save the return register on PPC,
136 since both values reside in R3. */
138 if (checksync && code_is_synchronized(code))
139 cd->stackframesize += 2;
142 /* create method header */
144 /* align stack to 16-bytes */
146 if (!code_is_leafmethod(code) || JITDATA_HAS_FLAG_VERBOSECALL(jd))
147 ALIGN_2(cd->stackframesize);
149 else if (code_is_leafmethod(code) && (cd->stackframesize == LA_SIZE_IN_POINTERS))
150 cd->stackframesize = 0;
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 code->synchronizedoffset = rd->memuse * 8;
157 /* REMOVEME: We still need it for exception handling in assembler. */
159 if (code_is_leafmethod(code))
160 (void) dseg_add_unique_s4(cd, 1);
162 (void) dseg_add_unique_s4(cd, 0);
164 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
165 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
167 #if defined(ENABLE_PROFILING)
168 /* generate method profiling code */
170 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
171 /* count frequency */
173 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
174 M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
175 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
176 M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
178 /* PROFILE_CYCLE_START; */
182 /* create stack frame (if necessary) */
184 if (!code_is_leafmethod(code)) {
186 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
189 if (cd->stackframesize)
190 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
192 /* save return address and used callee saved registers */
194 p = cd->stackframesize;
195 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
196 p--; M_IST(rd->savintregs[i], REG_SP, p * 8);
198 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
199 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
202 /* take arguments out of register or stack frame */
206 for (p = 0, l = 0; p < md->paramcount; p++) {
207 t = md->paramtypes[p].type;
208 varindex = jd->local_map[l * 5 + t];
211 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
214 if (varindex == UNUSED)
218 s1 = md->params[p].regoff;
220 if (IS_INT_LNG_TYPE(t)) {
221 if (!md->params[p].inmemory) {
222 if (!IS_INMEMORY(var->flags)) {
223 if (IS_2_WORD_TYPE(t))
224 M_LNGMOVE(s1, var->vv.regoff);
226 M_INTMOVE(s1, var->vv.regoff);
229 if (IS_2_WORD_TYPE(t))
230 M_LST(s1, REG_SP, var->vv.regoff);
232 M_IST(s1, REG_SP, var->vv.regoff);
236 if (!IS_INMEMORY(var->flags)) {
237 if (IS_2_WORD_TYPE(t))
238 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
240 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
244 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1);
245 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
246 if (IS_2_WORD_TYPE(t)) {
247 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1 + 4);
248 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
251 /* Reuse Memory Position on Caller Stack */
252 var->vv.regoff = cd->stackframesize * 8 + s1;
258 if (!md->params[p].inmemory) {
259 if (!IS_INMEMORY(var->flags))
260 M_FLTMOVE(s1, var->vv.regoff);
262 M_DST(s1, REG_SP, var->vv.regoff);
265 if (!IS_INMEMORY(var->flags))
266 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
269 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize * 8 + s1);
270 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
272 /* Reuse Memory Position on Caller Stack */
273 var->vv.regoff = cd->stackframesize * 8 + s1;
280 #if defined(ENABLE_THREADS)
281 /* call monitorenter function */
283 if (checksync && code_is_synchronized(code)) {
284 /* stack offset for monitor argument */
288 # if !defined(NDEBUG)
289 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
290 M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
292 for (p = 0; p < INT_ARG_CNT; p++)
293 M_IST(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
295 for (p = 0; p < FLT_ARG_CNT; p++)
296 M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
298 s1 += LA_SIZE_IN_POINTERS + ARG_CNT;
302 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
303 M_ALD(REG_ITMP3, REG_PV, disp);
306 /* get or test the lock object */
308 if (m->flags & ACC_STATIC) {
309 disp = dseg_add_address(cd, &m->clazz->object.header);
310 M_ALD(REG_A0, REG_PV, disp);
315 M_ALD_INTERN(REG_ZERO, REG_ZERO, TRAP_NullPointerException);
318 M_AST(REG_A0, REG_SP, s1 * 8);
321 # if !defined(NDEBUG)
322 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
323 for (p = 0; p < INT_ARG_CNT; p++)
324 M_ILD(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
326 for (p = 0; p < FLT_ARG_CNT; p++)
327 M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
329 M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
333 #endif /* defined(ENABLE_THREADS) */
335 /* call trace function */
337 emit_verbosecall_enter(jd);
340 /* end of header generation */
342 /* create replacement points */
344 REPLACEMENT_POINTS_INIT(cd, jd);
346 /* walk through all basic blocks */
348 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
350 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
352 if (bptr->flags >= BBREACHED) {
353 /* branch resolving */
355 codegen_resolve_branchrefs(cd, bptr);
357 /* handle replacement points */
359 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
361 #if defined(ENABLE_PROFILING)
362 /* generate basicblock profiling code */
364 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
365 /* count frequency */
367 disp = dseg_add_address(cd, code->bbfrequency);
368 M_ALD(REG_ITMP2, REG_PV, disp);
369 M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
370 M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
371 M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
373 /* if this is an exception handler, start profiling again */
375 /* if (bptr->type == BBTYPE_EXH) */
376 /* PROFILE_CYCLE_START; */
380 /* copy interface registers to their destination */
385 #if defined(ENABLE_LSRA)
387 while (src != NULL) {
389 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
390 /* d = reg_of_var(m, src, REG_ITMP1); */
391 if (!IS_INMEMORY(src->flags))
395 M_INTMOVE(REG_ITMP1, d);
396 emit_store(jd, NULL, src, d);
404 var = VAR(bptr->invars[len]);
405 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
406 d = codegen_reg_of_var(0, var, REG_ITMP1);
407 M_INTMOVE(REG_ITMP1, d);
408 emit_store(jd, NULL, var, d);
411 assert((var->flags & INOUT));
415 #if defined(ENABLE_LSRA)
418 /* walk through all instructions */
423 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
424 if (iptr->line != currentline) {
425 linenumbertable_list_entry_add(cd, iptr->line);
426 currentline = iptr->line;
429 MCODECHECK(64); /* an instruction usually needs < 64 words */
432 case ICMD_NOP: /* ... ==> ... */
433 case ICMD_POP: /* ..., value ==> ... */
434 case ICMD_POP2: /* ..., value, value ==> ... */
437 case ICMD_INLINE_START:
439 REPLACEMENT_POINT_INLINE_START(cd, iptr);
442 case ICMD_INLINE_BODY:
444 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
445 linenumbertable_list_entry_add_inline_start(cd, iptr);
446 linenumbertable_list_entry_add(cd, iptr->line);
449 case ICMD_INLINE_END:
451 linenumbertable_list_entry_add_inline_end(cd, iptr);
452 linenumbertable_list_entry_add(cd, iptr->line);
455 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
457 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
458 emit_nullpointer_check(cd, iptr, s1);
461 /* constant operations ************************************************/
463 case ICMD_ICONST: /* ... ==> ..., constant */
465 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
466 ICONST(d, iptr->sx.val.i);
467 emit_store_dst(jd, iptr, d);
470 case ICMD_LCONST: /* ... ==> ..., constant */
472 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
473 LCONST(d, iptr->sx.val.l);
474 emit_store_dst(jd, iptr, d);
477 case ICMD_FCONST: /* ... ==> ..., constant */
479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
480 disp = dseg_add_float(cd, iptr->sx.val.f);
481 M_FLD(d, REG_PV, disp);
482 emit_store_dst(jd, iptr, d);
485 case ICMD_DCONST: /* ... ==> ..., constant */
487 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
488 disp = dseg_add_double(cd, iptr->sx.val.d);
489 M_DLD(d, REG_PV, disp);
490 emit_store_dst(jd, iptr, d);
493 case ICMD_ACONST: /* ... ==> ..., constant */
495 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
497 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
498 constant_classref *cr = iptr->sx.val.c.ref;;
500 disp = dseg_add_unique_address(cd, cr);
502 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
506 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
508 M_ALD(d, REG_PV, disp);
509 emit_store_dst(jd, iptr, d);
513 /* load/store/copy/move operations ************************************/
515 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
516 case ICMD_ALOAD: /* s1 = local variable */
520 case ICMD_ISTORE: /* ..., value ==> ... */
532 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
537 /* integer operations *************************************************/
539 case ICMD_INEG: /* ..., value ==> ..., - value */
541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
544 emit_store_dst(jd, iptr, d);
547 case ICMD_LNEG: /* ..., value ==> ..., - value */
549 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
551 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
552 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
553 emit_store_dst(jd, iptr, d);
556 case ICMD_I2L: /* ..., value ==> ..., value */
558 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
560 M_INTMOVE(s1, GET_LOW_REG(d));
561 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
562 emit_store_dst(jd, iptr, d);
565 case ICMD_L2I: /* ..., value ==> ..., value */
567 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 emit_store_dst(jd, iptr, d);
581 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586 emit_store_dst(jd, iptr, d);
589 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
594 emit_store_dst(jd, iptr, d);
598 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
604 emit_store_dst(jd, iptr, d);
607 /* s1.localindex = variable, sx.val.i = constant*/
612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
613 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
614 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
615 M_IADD_IMM(s1, iptr->sx.val.i, d);
617 ICONST(REG_ITMP2, iptr->sx.val.i);
618 M_IADD(s1, REG_ITMP2, d);
620 /* XXX the old code for ICMD_IINC was as follows:
622 u4 m = iptr->sx.val.i;
626 M_ADDIS(s1, m >> 16, d);
628 M_IADD_IMM(s1, m & 0xffff, d);
631 emit_store_dst(jd, iptr, d);
634 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
636 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
637 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
639 M_ADDC(s1, s2, GET_LOW_REG(d));
640 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
641 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
642 M_ADDE(s1, s2, GET_HIGH_REG(d));
643 emit_store_dst(jd, iptr, d);
646 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
647 /* sx.val.l = constant */
649 s3 = iptr->sx.val.l & 0xffffffff;
650 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
652 if ((s3 >= -32768) && (s3 <= 32767))
653 M_ADDIC(s1, s3, GET_LOW_REG(d));
655 ICONST(REG_ITMP2, s3);
656 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
658 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
659 s3 = iptr->sx.val.l >> 32;
661 M_ADDME(s1, GET_HIGH_REG(d));
663 M_ADDZE(s1, GET_HIGH_REG(d));
665 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
666 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
668 emit_store_dst(jd, iptr, d);
671 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
675 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 emit_store_dst(jd, iptr, d);
680 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
681 /* sx.val.i = constant */
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
685 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
686 M_IADD_IMM(s1, -iptr->sx.val.i, d);
688 ICONST(REG_ITMP2, iptr->sx.val.i);
689 M_ISUB(s1, REG_ITMP2, d);
691 emit_store_dst(jd, iptr, d);
694 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
696 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
697 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
699 M_SUBC(s1, s2, GET_LOW_REG(d));
700 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
701 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
702 M_SUBE(s1, s2, GET_HIGH_REG(d));
703 emit_store_dst(jd, iptr, d);
706 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
707 /* sx.val.l = constant */
709 s3 = (-iptr->sx.val.l) & 0xffffffff;
710 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
712 if ((s3 >= -32768) && (s3 <= 32767)) {
713 M_ADDIC(s1, s3, GET_LOW_REG(d));
715 ICONST(REG_ITMP2, s3);
716 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
718 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
719 s3 = (-iptr->sx.val.l) >> 32;
721 M_ADDME(s1, GET_HIGH_REG(d));
723 M_ADDZE(s1, GET_HIGH_REG(d));
725 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
726 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
728 emit_store_dst(jd, iptr, d);
731 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
736 emit_arithmetic_check(cd, iptr, s2);
737 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
738 M_CMP(REG_ITMP3, s1);
739 M_BNE(3 + (s1 != d));
741 M_BNE(1 + (s1 != d));
745 emit_store_dst(jd, iptr, d);
748 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
753 emit_arithmetic_check(cd, iptr, s2);
754 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
755 M_CMP(REG_ITMP3, s1);
761 M_IDIV(s1, s2, REG_ITMP3);
762 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
763 M_ISUB(s1, REG_ITMP3, d);
764 emit_store_dst(jd, iptr, d);
767 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
768 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
770 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
771 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
773 /* XXX TODO: only do this if arithmetic check is really done! */
774 M_IOR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
775 /* XXX could be optimized */
776 emit_arithmetic_check(cd, iptr, REG_ITMP3);
778 bte = iptr->sx.s23.s3.bte;
779 disp = dseg_add_functionptr(cd, bte->fp);
780 M_ALD(REG_ITMP3, REG_PV, disp);
783 M_LNGMOVE(s1, REG_A0_A1_PACKED);
784 M_LNGMOVE(s2, REG_A2_A3_PACKED);
788 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
789 M_LNGMOVE(REG_RESULT_PACKED, d);
790 emit_store_dst(jd, iptr, d);
793 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
795 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
796 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
799 emit_store_dst(jd, iptr, d);
802 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
803 /* sx.val.i = constant */
805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
807 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
808 M_IMUL_IMM(s1, iptr->sx.val.i, d);
810 ICONST(REG_ITMP3, iptr->sx.val.i);
811 M_IMUL(s1, REG_ITMP3, d);
813 emit_store_dst(jd, iptr, d);
816 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
820 M_SRA_IMM(s1, iptr->sx.val.i, d);
822 emit_store_dst(jd, iptr, d);
825 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
827 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
828 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
829 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
830 M_IAND_IMM(s2, 0x1f, REG_ITMP3);
831 M_SLL(s1, REG_ITMP3, d);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
836 /* sx.val.i = constant */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
840 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
841 emit_store_dst(jd, iptr, d);
844 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
847 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
849 M_IAND_IMM(s2, 0x1f, REG_ITMP3);
850 M_SRA(s1, REG_ITMP3, d);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
855 /* sx.val.i = constant */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
859 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 M_IAND_IMM(s2, 0x1f, REG_ITMP2);
869 M_SRL(s1, REG_ITMP2, d);
870 emit_store_dst(jd, iptr, d);
873 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
874 /* sx.val.i = constant */
876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878 if (iptr->sx.val.i & 0x1f)
879 M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
883 emit_store_dst(jd, iptr, d);
886 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
888 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
889 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
890 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
892 emit_store_dst(jd, iptr, d);
895 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
896 /* sx.val.i = constant */
898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
901 M_IAND_IMM(s1, iptr->sx.val.i, d);
903 else if (iptr->sx.val.i == 0xffffff) {
904 M_RLWINM(s1, 0, 8, 31, d);
908 ICONST(REG_ITMP3, iptr->sx.val.i);
909 M_IAND(s1, REG_ITMP3, d);
911 emit_store_dst(jd, iptr, d);
914 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
916 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
917 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
918 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
919 M_IAND(s1, s2, GET_LOW_REG(d));
920 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
921 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
922 M_IAND(s1, s2, GET_HIGH_REG(d));
923 emit_store_dst(jd, iptr, d);
926 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
927 /* sx.val.l = constant */
929 s3 = iptr->sx.val.l & 0xffffffff;
930 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
932 if ((s3 >= 0) && (s3 <= 65535))
933 M_IAND_IMM(s1, s3, GET_LOW_REG(d));
935 ICONST(REG_ITMP3, s3);
936 M_IAND(s1, REG_ITMP3, GET_LOW_REG(d));
938 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
939 s3 = iptr->sx.val.l >> 32;
940 if ((s3 >= 0) && (s3 <= 65535))
941 M_IAND_IMM(s1, s3, GET_HIGH_REG(d));
943 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
944 M_IAND(s1, REG_ITMP3, GET_HIGH_REG(d));
946 emit_store_dst(jd, iptr, d);
949 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
950 /* sx.val.i = constant */
952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
953 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
954 M_MOV(s1, REG_ITMP2);
956 M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
957 if (iptr->sx.val.i >= 32768) {
958 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
959 M_IOR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
960 M_IADD(s1, REG_ITMP2, REG_ITMP2);
963 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
966 int b=0, m = iptr->sx.val.i;
969 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
971 M_ISUB(s1, REG_ITMP2, d);
972 emit_store_dst(jd, iptr, d);
975 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
977 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
978 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
979 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
981 emit_store_dst(jd, iptr, d);
984 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
985 /* sx.val.i = constant */
987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
989 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
990 M_IOR_IMM(s1, iptr->sx.val.i, d);
992 ICONST(REG_ITMP3, iptr->sx.val.i);
993 M_IOR(s1, REG_ITMP3, d);
995 emit_store_dst(jd, iptr, d);
998 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1000 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1001 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1002 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1003 M_IOR(s1, s2, GET_LOW_REG(d));
1004 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1005 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1006 M_IOR(s1, s2, GET_HIGH_REG(d));
1007 emit_store_dst(jd, iptr, d);
1010 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1011 /* sx.val.l = constant */
1013 s3 = iptr->sx.val.l & 0xffffffff;
1014 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1016 if ((s3 >= 0) && (s3 <= 65535))
1017 M_IOR_IMM(s1, s3, GET_LOW_REG(d));
1019 ICONST(REG_ITMP3, s3);
1020 M_IOR(s1, REG_ITMP3, GET_LOW_REG(d));
1022 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1023 s3 = iptr->sx.val.l >> 32;
1024 if ((s3 >= 0) && (s3 <= 65535))
1025 M_IOR_IMM(s1, s3, GET_HIGH_REG(d));
1027 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1028 M_IOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1030 emit_store_dst(jd, iptr, d);
1033 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1039 emit_store_dst(jd, iptr, d);
1042 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1043 /* sx.val.i = constant */
1045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1046 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1047 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1048 M_XOR_IMM(s1, iptr->sx.val.i, d);
1050 ICONST(REG_ITMP3, iptr->sx.val.i);
1051 M_XOR(s1, REG_ITMP3, d);
1053 emit_store_dst(jd, iptr, d);
1056 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1058 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1059 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1060 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1061 M_XOR(s1, s2, GET_LOW_REG(d));
1062 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1063 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1064 M_XOR(s1, s2, GET_HIGH_REG(d));
1065 emit_store_dst(jd, iptr, d);
1068 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1069 /* sx.val.l = constant */
1071 s3 = iptr->sx.val.l & 0xffffffff;
1072 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1073 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1074 if ((s3 >= 0) && (s3 <= 65535))
1075 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1077 ICONST(REG_ITMP3, s3);
1078 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1080 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1081 s3 = iptr->sx.val.l >> 32;
1082 if ((s3 >= 0) && (s3 <= 65535))
1083 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1085 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1086 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1093 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1094 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1095 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1096 vm_abort("codegen: implement ICMD_LCMP!");
1097 emit_store_dst(jd, iptr, d);
1101 /* floating operations ************************************************/
1103 case ICMD_FNEG: /* ..., value ==> ..., - value */
1105 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1106 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_DNEG: /* ..., value ==> ..., - value */
1113 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1114 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1116 emit_store_dst(jd, iptr, d);
1119 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1121 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1122 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1123 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1130 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1131 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1132 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1134 emit_store_dst(jd, iptr, d);
1137 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1139 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1140 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1141 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1143 emit_store_dst(jd, iptr, d);
1146 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1148 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1149 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1150 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1152 emit_store_dst(jd, iptr, d);
1155 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1157 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1158 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1159 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1161 emit_store_dst(jd, iptr, d);
1164 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1166 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1167 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1168 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1175 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1179 emit_store_dst(jd, iptr, d);
1182 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1184 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1185 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1186 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1194 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1195 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1197 disp = dseg_add_float(cd, 0.0);
1198 M_FLD(REG_FTMP2, REG_PV, disp);
1199 M_FCMPU(s1, REG_FTMP2);
1201 disp = dseg_add_unique_s4(cd, 0);
1202 M_CVTDL_C(s1, REG_FTMP1);
1203 M_LDA(REG_ITMP1, REG_PV, disp);
1204 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1205 M_ILD(d, REG_PV, disp);
1206 emit_store_dst(jd, iptr, d);
1209 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1211 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1212 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1214 emit_store_dst(jd, iptr, d);
1217 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1219 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1220 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1222 emit_store_dst(jd, iptr, d);
1225 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1226 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1228 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1229 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1230 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1232 M_IADD_IMM(REG_ZERO, -1, d);
1235 M_IADD_IMM(REG_ZERO, 0, d);
1237 M_IADD_IMM(REG_ZERO, 1, d);
1238 emit_store_dst(jd, iptr, d);
1241 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1242 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1244 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1245 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1246 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1248 M_IADD_IMM(REG_ZERO, 1, d);
1251 M_IADD_IMM(REG_ZERO, 0, d);
1253 M_IADD_IMM(REG_ZERO, -1, d);
1254 emit_store_dst(jd, iptr, d);
1258 /* memory operations **************************************************/
1260 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1264 /* implicit null-pointer check */
1265 M_ILD(d, s1, OFFSET(java_array_t, size));
1266 emit_store_dst(jd, iptr, d);
1269 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1272 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1273 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1274 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1275 M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1276 /* implicit null-pointer check */
1277 M_LBZX(d, s1, REG_ITMP2);
1279 emit_store_dst(jd, iptr, d);
1282 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1284 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1285 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1286 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1287 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1288 M_SLL_IMM(s2, 1, REG_ITMP2);
1289 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1290 /* implicit null-pointer check */
1291 M_LHZX(d, s1, REG_ITMP2);
1292 emit_store_dst(jd, iptr, d);
1295 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1297 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1298 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1299 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1300 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1301 M_SLL_IMM(s2, 1, REG_ITMP2);
1302 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1303 /* implicit null-pointer check */
1304 M_LHAX(d, s1, REG_ITMP2);
1305 emit_store_dst(jd, iptr, d);
1308 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1310 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1311 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1312 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1313 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1314 M_SLL_IMM(s2, 2, REG_ITMP2);
1315 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1316 /* implicit null-pointer check */
1317 M_LWZX(d, s1, REG_ITMP2);
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1326 /* implicit null-pointer check */
1327 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1328 M_SLL_IMM(s2, 3, REG_ITMP2);
1329 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1330 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray_t, data[0]));
1331 emit_store_dst(jd, iptr, d);
1334 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1337 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1338 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1339 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1340 M_SLL_IMM(s2, 2, REG_ITMP2);
1341 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1342 /* implicit null-pointer check */
1343 M_LFSX(d, s1, REG_ITMP2);
1344 emit_store_dst(jd, iptr, d);
1347 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1350 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1351 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1352 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1353 M_SLL_IMM(s2, 3, REG_ITMP2);
1354 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1355 /* implicit null-pointer check */
1356 M_LFDX(d, s1, REG_ITMP2);
1357 emit_store_dst(jd, iptr, d);
1360 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1362 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1363 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1365 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1366 M_SLL_IMM(s2, 2, REG_ITMP2);
1367 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1368 /* implicit null-pointer check */
1369 M_LWZX(d, s1, REG_ITMP2);
1370 emit_store_dst(jd, iptr, d);
1374 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1377 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1378 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1379 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1380 M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1381 /* implicit null-pointer check */
1382 M_STBX(s3, s1, REG_ITMP2);
1385 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1387 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1388 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1389 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1390 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1391 M_SLL_IMM(s2, 1, REG_ITMP2);
1392 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1393 /* implicit null-pointer check */
1394 M_STHX(s3, s1, REG_ITMP2);
1397 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1399 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1400 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1401 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1402 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1403 M_SLL_IMM(s2, 1, REG_ITMP2);
1404 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1405 /* implicit null-pointer check */
1406 M_STHX(s3, s1, REG_ITMP2);
1409 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1412 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1413 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1414 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1415 M_SLL_IMM(s2, 2, REG_ITMP2);
1416 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1417 /* implicit null-pointer check */
1418 M_STWX(s3, s1, REG_ITMP2);
1421 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1423 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1424 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1425 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1426 s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1427 M_SLL_IMM(s2, 3, REG_ITMP2);
1428 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray_t, data[0]), REG_ITMP2);
1429 /* implicit null-pointer check */
1430 M_STWX(s3, s1, REG_ITMP2);
1431 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1432 s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1433 M_STWX(s3, s1, REG_ITMP2);
1436 case ICMD_FASTORE: /* ..., 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(jd, iptr, REG_FTMP3);
1442 M_SLL_IMM(s2, 2, REG_ITMP2);
1443 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1444 /* implicit null-pointer check */
1445 M_STFSX(s3, s1, REG_ITMP2);
1448 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1451 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1452 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1453 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1454 M_SLL_IMM(s2, 3, REG_ITMP2);
1455 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1456 /* implicit null-pointer check */
1457 M_STFDX(s3, s1, REG_ITMP2);
1460 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1462 s1 = emit_load_s1(jd, iptr, REG_A0);
1463 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1464 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1465 s3 = emit_load_s3(jd, iptr, REG_A1);
1467 /* XXX what if array is NULL */
1468 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1469 M_ALD(REG_ITMP3, REG_PV, disp);
1472 M_INTMOVE(s1, REG_A0);
1473 M_INTMOVE(s3, REG_A1);
1476 emit_arraystore_check(cd, iptr);
1478 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1479 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1480 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1481 M_SLL_IMM(s2, 2, REG_ITMP2);
1482 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1483 /* implicit null-pointer check */
1484 M_STWX(s3, s1, REG_ITMP2);
1488 case ICMD_GETSTATIC: /* ... ==> ..., value */
1490 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1491 uf = iptr->sx.s23.s3.uf;
1492 fieldtype = uf->fieldref->parseddesc.fd->type;
1493 disp = dseg_add_unique_address(cd, uf);
1495 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1498 fi = iptr->sx.s23.s3.fmiref->p.field;
1499 fieldtype = fi->type;
1500 disp = dseg_add_address(cd, fi->value);
1502 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1503 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1507 M_ALD(REG_ITMP1, REG_PV, disp);
1508 switch (fieldtype) {
1510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1511 M_ILD_INTERN(d, REG_ITMP1, 0);
1514 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1515 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1516 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1520 M_ALD_INTERN(d, REG_ITMP1, 0);
1523 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1524 M_FLD_INTERN(d, REG_ITMP1, 0);
1527 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1528 M_DLD_INTERN(d, REG_ITMP1, 0);
1531 emit_store_dst(jd, iptr, d);
1534 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1536 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1537 uf = iptr->sx.s23.s3.uf;
1538 fieldtype = uf->fieldref->parseddesc.fd->type;
1539 disp = dseg_add_unique_address(cd, uf);
1541 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1544 fi = iptr->sx.s23.s3.fmiref->p.field;
1545 fieldtype = fi->type;
1546 disp = dseg_add_address(cd, fi->value);
1548 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1549 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1553 M_ALD(REG_ITMP1, REG_PV, disp);
1554 switch (fieldtype) {
1556 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1557 M_IST_INTERN(s1, REG_ITMP1, 0);
1560 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1561 M_LST_INTERN(s1, REG_ITMP1, 0);
1564 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1565 M_AST_INTERN(s1, REG_ITMP1, 0);
1568 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1569 M_FST_INTERN(s1, REG_ITMP1, 0);
1572 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1573 M_DST_INTERN(s1, REG_ITMP1, 0);
1579 case ICMD_GETFIELD: /* ... ==> ..., value */
1581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1583 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1584 uf = iptr->sx.s23.s3.uf;
1585 fieldtype = uf->fieldref->parseddesc.fd->type;
1588 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1591 fi = iptr->sx.s23.s3.fmiref->p.field;
1592 fieldtype = fi->type;
1596 /* implicit null-pointer check */
1597 switch (fieldtype) {
1599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1604 if (GET_HIGH_REG(d) == s1) {
1605 M_ILD(GET_LOW_REG(d), s1, disp + 4);
1606 M_ILD(GET_HIGH_REG(d), s1, disp);
1609 M_ILD(GET_HIGH_REG(d), s1, disp);
1610 M_ILD(GET_LOW_REG(d), s1, disp + 4);
1614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1618 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1622 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1626 emit_store_dst(jd, iptr, d);
1629 case ICMD_PUTFIELD: /* ..., value ==> ... */
1631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1633 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1634 uf = iptr->sx.s23.s3.uf;
1635 fieldtype = uf->fieldref->parseddesc.fd->type;
1639 fi = iptr->sx.s23.s3.fmiref->p.field;
1640 fieldtype = fi->type;
1644 if (IS_INT_LNG_TYPE(fieldtype)) {
1645 if (IS_2_WORD_TYPE(fieldtype))
1646 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1651 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1653 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1654 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1656 /* implicit null-pointer check */
1657 switch (fieldtype) {
1659 M_IST(s2, s1, disp);
1662 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
1663 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
1666 M_AST(s2, s1, disp);
1669 M_FST(s2, s1, disp);
1672 M_DST(s2, s1, disp);
1678 /* branch operations **************************************************/
1680 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1683 M_INTMOVE(s1, REG_ITMP1_XPTR);
1685 #ifdef ENABLE_VERIFIER
1686 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1687 unresolved_class *uc = iptr->sx.s23.s2.uc;
1689 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1691 #endif /* ENABLE_VERIFIER */
1693 disp = dseg_add_functionptr(cd, asm_handle_exception);
1694 M_ALD(REG_ITMP2, REG_PV, disp);
1697 if (code_is_leafmethod(code))
1698 M_MFLR(REG_ITMP3); /* save LR */
1700 M_BL(0); /* get current PC */
1701 M_MFLR(REG_ITMP2_XPC);
1703 if (code_is_leafmethod(code))
1704 M_MTLR(REG_ITMP3); /* restore LR */
1706 M_RTS; /* jump to CTR */
1710 case ICMD_GOTO: /* ... ==> ... */
1711 case ICMD_RET: /* ... ==> ... */
1713 emit_br(cd, iptr->dst.block);
1717 case ICMD_JSR: /* ... ==> ... */
1719 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1723 case ICMD_IFNULL: /* ..., value ==> ... */
1724 case ICMD_IFNONNULL:
1726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1728 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1736 case ICMD_IFEQ: /* ..., value ==> ... */
1738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1739 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1740 M_CMPI(s1, iptr->sx.val.i);
1742 ICONST(REG_ITMP2, iptr->sx.val.i);
1743 M_CMP(s1, REG_ITMP2);
1745 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1749 case ICMD_IF_LEQ: /* ..., value ==> ... */
1751 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1752 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1753 if (iptr->sx.val.l == 0) {
1754 M_IOR_TST(s1, s2, REG_ITMP3);
1756 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1757 M_XOR_IMM(s2, 0, REG_ITMP2);
1758 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1759 M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1762 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1763 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1764 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1765 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1766 M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1768 emit_beq(cd, iptr->dst.block);
1771 case ICMD_IF_LLT: /* ..., value ==> ... */
1773 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1774 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1775 if (iptr->sx.val.l == 0) {
1776 /* if high word is less than zero, the whole long is too */
1778 emit_blt(cd, iptr->dst.block);
1780 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1782 emit_blt(cd, iptr->dst.block);
1783 emit_label_bgt(cd, BRANCH_LABEL_1);
1784 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1785 emit_blt(cd, iptr->dst.block);
1786 emit_label(cd, BRANCH_LABEL_1);
1789 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1790 M_CMP(s2, REG_ITMP3);
1791 emit_blt(cd, iptr->dst.block);
1792 emit_label_bgt(cd, BRANCH_LABEL_1);
1793 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1794 M_CMPU(s1, REG_ITMP3);
1795 emit_blt(cd, iptr->dst.block);
1796 emit_label(cd, BRANCH_LABEL_1);
1800 case ICMD_IF_LLE: /* ..., value ==> ... */
1802 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1803 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1804 /* if (iptr->sx.val.l == 0) { */
1805 /* M_IOR(s1, s2, REG_ITMP3); */
1806 /* M_CMPI(REG_ITMP3, 0); */
1809 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1811 emit_blt(cd, iptr->dst.block);
1812 emit_label_bgt(cd, BRANCH_LABEL_1);
1813 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1816 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1817 M_CMP(s2, REG_ITMP3);
1818 emit_blt(cd, iptr->dst.block);
1819 emit_label_bgt(cd, BRANCH_LABEL_1);
1820 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1821 M_CMPU(s1, REG_ITMP3);
1823 emit_ble(cd, iptr->dst.block);
1824 emit_label(cd, BRANCH_LABEL_1);
1827 case ICMD_IF_LNE: /* ..., value ==> ... */
1829 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1830 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1831 if (iptr->sx.val.l == 0) {
1832 M_IOR_TST(s1, s2, REG_ITMP3);
1834 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1835 M_XOR_IMM(s2, 0, REG_ITMP2);
1836 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1837 M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1840 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1841 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1842 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1843 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1844 M_IOR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1846 emit_bne(cd, iptr->dst.block);
1849 case ICMD_IF_LGT: /* ..., value ==> ... */
1851 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1852 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1853 /* if (iptr->sx.val.l == 0) { */
1854 /* M_IOR(s1, s2, REG_ITMP3); */
1855 /* M_CMPI(REG_ITMP3, 0); */
1858 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1860 emit_bgt(cd, iptr->dst.block);
1861 emit_label_blt(cd, BRANCH_LABEL_1);
1862 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1865 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1866 M_CMP(s2, REG_ITMP3);
1867 emit_bgt(cd, iptr->dst.block);
1868 emit_label_blt(cd, BRANCH_LABEL_1);
1869 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1870 M_CMPU(s1, REG_ITMP3);
1872 emit_bgt(cd, iptr->dst.block);
1873 emit_label(cd, BRANCH_LABEL_1);
1876 case ICMD_IF_LGE: /* ..., value ==> ... */
1878 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1879 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1880 if (iptr->sx.val.l == 0) {
1881 /* if high word is greater equal zero, the whole long is too */
1883 emit_bge(cd, iptr->dst.block);
1885 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1887 emit_bgt(cd, iptr->dst.block);
1888 emit_label_blt(cd, BRANCH_LABEL_1);
1889 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1890 emit_bge(cd, iptr->dst.block);
1891 emit_label(cd, BRANCH_LABEL_1);
1894 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1895 M_CMP(s2, REG_ITMP3);
1896 emit_bgt(cd, iptr->dst.block);
1897 emit_label_blt(cd, BRANCH_LABEL_1);
1898 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1899 M_CMPU(s1, REG_ITMP3);
1900 emit_bge(cd, iptr->dst.block);
1901 emit_label(cd, BRANCH_LABEL_1);
1905 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1906 case ICMD_IF_ICMPNE:
1907 case ICMD_IF_ICMPLT:
1908 case ICMD_IF_ICMPGT:
1909 case ICMD_IF_ICMPLE:
1910 case ICMD_IF_ICMPGE:
1912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1913 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1915 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1918 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1919 case ICMD_IF_ACMPNE:
1921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1922 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1924 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1927 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1929 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1930 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1932 emit_label_bne(cd, BRANCH_LABEL_1);
1933 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1934 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1936 emit_beq(cd, iptr->dst.block);
1937 emit_label(cd, BRANCH_LABEL_1);
1940 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1942 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1943 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1945 emit_bne(cd, iptr->dst.block);
1946 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1947 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1949 emit_bne(cd, iptr->dst.block);
1952 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1954 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1955 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1957 emit_blt(cd, iptr->dst.block);
1958 emit_label_bgt(cd, BRANCH_LABEL_1);
1959 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1960 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1962 emit_blt(cd, iptr->dst.block);
1963 emit_label(cd, BRANCH_LABEL_1);
1966 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1968 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1969 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1971 emit_bgt(cd, iptr->dst.block);
1972 emit_label_blt(cd, BRANCH_LABEL_1);
1973 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1974 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1976 emit_bgt(cd, iptr->dst.block);
1977 emit_label(cd, BRANCH_LABEL_1);
1980 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1982 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1983 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1985 emit_blt(cd, iptr->dst.block);
1986 emit_label_bgt(cd, BRANCH_LABEL_1);
1987 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1988 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1990 emit_ble(cd, iptr->dst.block);
1991 emit_label(cd, BRANCH_LABEL_1);
1994 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1996 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1997 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1999 emit_bgt(cd, iptr->dst.block);
2000 emit_label_blt(cd, BRANCH_LABEL_1);
2001 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2002 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2004 emit_bge(cd, iptr->dst.block);
2005 emit_label(cd, BRANCH_LABEL_1);
2008 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2010 REPLACEMENT_POINT_RETURN(cd, iptr);
2011 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2012 M_INTMOVE(s1, REG_RESULT);
2013 goto nowperformreturn;
2015 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2017 REPLACEMENT_POINT_RETURN(cd, iptr);
2018 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2019 M_INTMOVE(s1, REG_RESULT);
2021 #ifdef ENABLE_VERIFIER
2022 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2023 unresolved_class *uc = iptr->sx.s23.s2.uc;
2025 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2027 #endif /* ENABLE_VERIFIER */
2028 goto nowperformreturn;
2030 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2032 REPLACEMENT_POINT_RETURN(cd, iptr);
2033 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2034 M_LNGMOVE(s1, REG_RESULT_PACKED);
2035 goto nowperformreturn;
2037 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2040 REPLACEMENT_POINT_RETURN(cd, iptr);
2041 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2042 M_FLTMOVE(s1, REG_FRESULT);
2043 goto nowperformreturn;
2045 case ICMD_RETURN: /* ... ==> ... */
2047 REPLACEMENT_POINT_RETURN(cd, iptr);
2053 p = cd->stackframesize;
2055 /* call trace function */
2057 emit_verbosecall_exit(jd);
2059 #if defined(ENABLE_THREADS)
2060 if (checksync && code_is_synchronized(code)) {
2061 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2062 M_ALD(REG_ITMP3, REG_PV, disp);
2065 /* we need to save the proper return value */
2067 switch (iptr->opc) {
2069 M_IST(REG_RESULT2, REG_SP, rd->memuse * 8 + 8);
2073 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 4);
2077 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 4);
2081 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2084 /* and now restore the proper return value */
2086 switch (iptr->opc) {
2088 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 8 + 8);
2092 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 4);
2096 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 4);
2102 /* restore return address */
2104 if (!code_is_leafmethod(code)) {
2105 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2106 may have a displacement overflow. */
2108 M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
2112 /* restore saved registers */
2114 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2115 p--; M_ILD(rd->savintregs[i], REG_SP, p * 8);
2117 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2118 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2121 /* deallocate stack */
2123 if (cd->stackframesize)
2124 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2132 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2135 branch_target_t *table;
2137 table = iptr->dst.table;
2139 l = iptr->sx.s23.s2.tablelow;
2140 i = iptr->sx.s23.s3.tablehigh;
2142 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2144 M_INTMOVE(s1, REG_ITMP1);
2145 else if (l <= 32768)
2146 M_LDA(REG_ITMP1, s1, -l);
2148 ICONST(REG_ITMP2, l);
2149 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2156 M_CMPUI(REG_ITMP1, i - 1);
2157 emit_bgt(cd, table[0].block);
2159 /* build jump table top down and use address of lowest entry */
2164 dseg_add_target(cd, table->block);
2168 /* length of dataseg after last dseg_add_target is used by load */
2170 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2171 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2172 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2180 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2183 lookup_target_t *lookup;
2185 lookup = iptr->dst.lookup;
2187 i = iptr->sx.s23.s2.lookupcount;
2189 MCODECHECK((i<<2)+8);
2190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2193 if ((lookup->value >= -32768) && (lookup->value <= 32767)) {
2194 M_CMPI(s1, lookup->value);
2197 disp = dseg_add_s4(cd, lookup->value);
2198 M_ILD(REG_ITMP2, REG_PV, disp);
2199 M_CMP(s1, REG_ITMP2);
2201 emit_beq(cd, lookup->target.block);
2205 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2211 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2213 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2215 bte = iptr->sx.s23.s3.bte;
2219 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2221 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2222 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2223 case ICMD_INVOKEINTERFACE:
2225 REPLACEMENT_POINT_INVOKE(cd, iptr);
2227 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2229 um = iptr->sx.s23.s3.um;
2230 md = um->methodref->parseddesc.md;
2233 lm = iptr->sx.s23.s3.fmiref->p.method;
2235 md = lm->parseddesc;
2241 MCODECHECK((i << 1) + 64);
2243 /* Copy arguments to registers or stack location. */
2245 for (i = i - 1; i >= 0; i--) {
2246 var = VAR(iptr->sx.s23.s2.args[i]);
2247 d = md->params[i].regoff;
2249 /* Already pre-allocated? */
2251 if (var->flags & PREALLOC)
2254 if (!md->params[i].inmemory) {
2255 s1 = emit_load(jd, iptr, var, d);
2257 switch (var->type) {
2274 switch (var->type) {
2277 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2278 M_IST(s1, REG_SP, d);
2282 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2283 M_LST(s1, REG_SP, d);
2288 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2289 M_DST(s1, REG_SP, d);
2295 switch (iptr->opc) {
2297 if (bte->stub == NULL)
2298 disp = dseg_add_functionptr(cd, bte->fp);
2300 disp = dseg_add_functionptr(cd, bte->stub);
2302 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
2304 /* generate the actual call */
2308 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2309 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2310 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2312 M_LDA(REG_PV, REG_ITMP1, -disp);
2315 case ICMD_INVOKESPECIAL:
2316 emit_nullpointer_check(cd, iptr, REG_A0);
2319 case ICMD_INVOKESTATIC:
2321 disp = dseg_add_unique_address(cd, um);
2323 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2327 disp = dseg_add_address(cd, lm->stubroutine);
2329 M_ALD(REG_PV, REG_PV, disp);
2331 /* generate the actual call */
2335 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2336 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2338 M_LDA(REG_PV, REG_ITMP1, -disp);
2341 case ICMD_INVOKEVIRTUAL:
2343 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2348 s1 = OFFSET(vftbl_t, table[0]) +
2349 sizeof(methodptr) * lm->vftblindex;
2352 /* implicit null-pointer check */
2353 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2354 M_ALD(REG_PV, REG_METHODPTR, s1);
2356 /* generate the actual call */
2360 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2361 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2363 M_LDA(REG_PV, REG_ITMP1, -disp);
2366 case ICMD_INVOKEINTERFACE:
2368 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2374 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2375 sizeof(methodptr*) * lm->clazz->index;
2377 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
2380 /* implicit null-pointer check */
2381 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2382 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2383 M_ALD(REG_PV, REG_METHODPTR, s2);
2385 /* generate the actual call */
2389 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2390 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2392 M_LDA(REG_PV, REG_ITMP1, -disp);
2396 /* Store return value. */
2398 switch (md->returntype.type) {
2401 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2402 M_INTMOVE(REG_RESULT, s1);
2403 emit_store_dst(jd, iptr, s1);
2407 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2408 M_LNGMOVE(REG_RESULT_PACKED, s1);
2409 emit_store_dst(jd, iptr, s1);
2414 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2415 M_FLTMOVE(REG_FRESULT, s1);
2416 emit_store_dst(jd, iptr, s1);
2425 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2427 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2428 /* object type cast-check */
2433 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2438 super = iptr->sx.s23.s3.c.cls;
2439 superindex = super->index;
2442 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2444 /* if class is not resolved, check which code to call */
2446 if (super == NULL) {
2448 emit_label_beq(cd, BRANCH_LABEL_1);
2450 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2452 patcher_add_patch_ref(jd,
2453 PATCHER_resolve_classref_to_flags,
2454 iptr->sx.s23.s3.c.ref,
2457 M_ILD(REG_ITMP2, REG_PV, disp);
2458 M_IAND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2459 emit_label_beq(cd, BRANCH_LABEL_2);
2462 /* interface checkcast code */
2464 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2465 if (super == NULL) {
2466 patcher_add_patch_ref(jd,
2467 PATCHER_checkcast_interface,
2468 iptr->sx.s23.s3.c.ref,
2473 emit_label_beq(cd, BRANCH_LABEL_3);
2476 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2477 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2478 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2479 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2481 M_ALD(REG_ITMP3, REG_ITMP2,
2482 OFFSET(vftbl_t, interfacetable[0]) -
2483 superindex * sizeof(methodptr*));
2485 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2488 emit_label_br(cd, BRANCH_LABEL_4);
2490 emit_label(cd, BRANCH_LABEL_3);
2493 /* class checkcast code */
2495 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2496 if (super == NULL) {
2497 emit_label(cd, BRANCH_LABEL_2);
2499 disp = dseg_add_unique_address(cd, NULL);
2501 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2502 iptr->sx.s23.s3.c.ref,
2506 disp = dseg_add_address(cd, super->vftbl);
2509 emit_label_beq(cd, BRANCH_LABEL_5);
2512 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2514 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2515 M_ALD(REG_ITMP2, REG_PV, disp);
2516 if (s1 != REG_ITMP1) {
2517 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
2518 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2520 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
2523 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2524 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2525 M_ALD(REG_ITMP2, REG_PV, disp);
2526 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2528 M_CMPU(REG_ITMP3, REG_ITMP2);
2529 emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
2532 emit_label(cd, BRANCH_LABEL_5);
2535 if (super == NULL) {
2536 emit_label(cd, BRANCH_LABEL_1);
2537 emit_label(cd, BRANCH_LABEL_4);
2540 d = codegen_reg_of_dst(jd, iptr, s1);
2543 /* array type cast-check */
2545 s1 = emit_load_s1(jd, iptr, REG_A0);
2546 M_INTMOVE(s1, REG_A0);
2548 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2549 disp = dseg_add_unique_address(cd, NULL);
2551 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2552 iptr->sx.s23.s3.c.ref,
2556 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2558 M_ALD(REG_A1, REG_PV, disp);
2559 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2560 M_ALD(REG_ITMP2, REG_PV, disp);
2564 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2567 d = codegen_reg_of_dst(jd, iptr, s1);
2570 emit_store_dst(jd, iptr, d);
2573 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2579 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2584 super = iptr->sx.s23.s3.c.cls;
2585 superindex = super->index;
2588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2590 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2592 M_MOV(s1, REG_ITMP1);
2598 /* if class is not resolved, check which code to call */
2600 if (super == NULL) {
2602 emit_label_beq(cd, BRANCH_LABEL_1);
2604 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2606 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2607 iptr->sx.s23.s3.c.ref, disp);
2609 M_ILD(REG_ITMP3, REG_PV, disp);
2610 M_IAND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2611 emit_label_beq(cd, BRANCH_LABEL_2);
2614 /* interface instanceof code */
2616 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2617 if (super == NULL) {
2618 patcher_add_patch_ref(jd,
2619 PATCHER_instanceof_interface,
2620 iptr->sx.s23.s3.c.ref, 0);
2624 emit_label_beq(cd, BRANCH_LABEL_3);
2627 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2628 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2629 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2631 M_ALD(REG_ITMP1, REG_ITMP1,
2632 OFFSET(vftbl_t, interfacetable[0]) -
2633 superindex * sizeof(methodptr*));
2636 M_IADD_IMM(REG_ZERO, 1, d);
2639 emit_label_br(cd, BRANCH_LABEL_4);
2641 emit_label(cd, BRANCH_LABEL_3);
2644 /* class instanceof code */
2646 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2647 if (super == NULL) {
2648 emit_label(cd, BRANCH_LABEL_2);
2650 disp = dseg_add_unique_address(cd, NULL);
2652 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2653 iptr->sx.s23.s3.c.ref,
2657 disp = dseg_add_address(cd, super->vftbl);
2660 emit_label_beq(cd, BRANCH_LABEL_5);
2663 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2664 M_ALD(REG_ITMP2, REG_PV, disp);
2666 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2667 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2668 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2670 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2671 M_CMPU(REG_ITMP1, REG_ITMP2);
2674 M_IADD_IMM(REG_ZERO, 1, d);
2677 emit_label(cd, BRANCH_LABEL_5);
2680 if (super == NULL) {
2681 emit_label(cd, BRANCH_LABEL_1);
2682 emit_label(cd, BRANCH_LABEL_4);
2685 emit_store_dst(jd, iptr, d);
2689 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2691 /* check for negative sizes and copy sizes to stack if necessary */
2693 MCODECHECK((iptr->s1.argcount << 1) + 64);
2695 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2696 var = VAR(iptr->sx.s23.s2.args[s1]);
2698 /* copy SAVEDVAR sizes to stack */
2700 /* Already Preallocated? */
2701 if (!(var->flags & PREALLOC)) {
2702 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2703 #if defined(__DARWIN__)
2704 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
2706 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
2711 /* a0 = dimension count */
2713 ICONST(REG_A0, iptr->s1.argcount);
2715 /* is patcher function set? */
2717 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2718 disp = dseg_add_unique_address(cd, NULL);
2720 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2721 iptr->sx.s23.s3.c.ref, disp);
2724 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2726 /* a1 = arraydescriptor */
2728 M_ALD(REG_A1, REG_PV, disp);
2730 /* a2 = pointer to dimensions = stack pointer */
2732 #if defined(__DARWIN__)
2733 M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 4);
2735 M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 4);
2738 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2739 M_ALD(REG_ITMP3, REG_PV, disp);
2743 /* check for exception before result assignment */
2745 emit_exception_check(cd, iptr);
2747 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2748 M_INTMOVE(REG_RESULT, d);
2749 emit_store_dst(jd, iptr, d);
2753 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2758 } /* for instruction */
2760 } /* if (bptr -> flags >= BBREACHED) */
2761 } /* for basic block */
2763 /* generate traps */
2765 emit_patcher_traps(jd);
2767 /* everything's ok */
2773 /* codegen_emit_stub_native ****************************************************
2775 Emits a stub routine which calls a native method.
2777 *******************************************************************************/
2779 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2785 s4 i, j; /* count variables */
2794 /* Get required compiler data. */
2800 /* set some variables */
2804 /* calculate stackframe size */
2806 cd->stackframesize =
2807 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2808 sizeof(localref_table) / SIZEOF_VOID_P +
2809 4 + /* 4 stackframeinfo arguments (darwin) */
2813 /* keep stack 16-byte aligned */
2815 ALIGN_2(cd->stackframesize);
2817 /* create method header */
2819 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2820 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2821 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2822 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2823 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2824 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2829 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
2830 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
2832 #if defined(ENABLE_GC_CACAO)
2833 /* Save callee saved integer registers in stackframeinfo (GC may
2834 need to recover them during a collection). */
2836 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
2837 OFFSET(stackframeinfo_t, intregs);
2839 for (i = 0; i < INT_SAV_CNT; i++)
2840 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
2843 /* save integer and float argument registers */
2845 for (i = 0; i < md->paramcount; i++) {
2846 if (!md->params[i].inmemory) {
2847 s1 = md->params[i].regoff;
2849 switch (md->paramtypes[i].type) {
2852 M_IST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2855 M_LST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2859 M_DST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2865 /* create native stack info */
2867 M_MOV(REG_SP, REG_A0);
2868 M_MOV(REG_PV, REG_A1);
2869 disp = dseg_add_functionptr(cd, codegen_start_native_call);
2870 M_ALD(REG_ITMP1, REG_PV, disp);
2874 /* remember class argument */
2876 if (m->flags & ACC_STATIC)
2877 M_MOV(REG_RESULT, REG_ITMP3);
2879 /* restore integer and float argument registers */
2881 for (i = 0; i < md->paramcount; i++) {
2882 if (!md->params[i].inmemory) {
2883 s1 = md->params[i].regoff;
2885 switch (md->paramtypes[i].type) {
2888 M_ILD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2891 M_LLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2895 M_DLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
2901 /* copy or spill arguments to new locations */
2903 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
2904 t = md->paramtypes[i].type;
2906 if (!md->params[i].inmemory) {
2907 s1 = md->params[i].regoff;
2908 s2 = nmd->params[j].regoff;
2913 if (!nmd->params[j].inmemory)
2916 M_IST(s1, REG_SP, s2);
2920 if (!nmd->params[j].inmemory)
2923 M_LST(s1, REG_SP, s2);
2928 /* We only copy spilled float arguments, as the float
2929 argument registers keep unchanged. */
2934 s1 = md->params[i].regoff + cd->stackframesize * 8;
2935 s2 = nmd->params[j].regoff;
2940 M_ILD(REG_ITMP1, REG_SP, s1);
2941 M_IST(REG_ITMP1, REG_SP, s2);
2945 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
2946 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
2950 M_DLD(REG_FTMP1, REG_SP, s1);
2951 M_FST(REG_FTMP1, REG_SP, s2);
2955 M_DLD(REG_FTMP1, REG_SP, s1);
2956 M_DST(REG_FTMP1, REG_SP, s2);
2962 /* Handle native Java methods. */
2964 if (m->flags & ACC_NATIVE) {
2965 /* put class into second argument register */
2967 if (m->flags & ACC_STATIC)
2968 M_MOV(REG_ITMP3, REG_A1);
2970 /* put env into first argument register */
2972 disp = dseg_add_address(cd, VM_get_jnienv());
2973 M_ALD(REG_A0, REG_PV, disp);
2976 /* Call the native function. */
2978 disp = dseg_add_functionptr(cd, f);
2979 M_ALD(REG_ITMP3, REG_PV, disp);
2983 /* save return value */
2985 switch (md->returntype.type) {
2988 M_IST(REG_RESULT, REG_SP, LA_SIZE + 2 * 4);
2991 M_LST(REG_RESULT_PACKED, REG_SP, LA_SIZE + 2 * 4);
2995 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 2 * 4);
3001 /* remove native stackframe info */
3003 M_MOV(REG_SP, REG_A0);
3004 M_MOV(REG_PV, REG_A1);
3005 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3006 M_ALD(REG_ITMP1, REG_PV, disp);
3009 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3011 /* restore return value */
3013 switch (md->returntype.type) {
3016 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 2 * 4);
3019 M_LLD(REG_RESULT_PACKED, REG_SP, LA_SIZE + 2 * 4);
3023 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 2 * 4);
3029 #if defined(ENABLE_GC_CACAO)
3030 /* Restore callee saved integer registers from stackframeinfo (GC
3031 might have modified them during a collection). */
3033 disp = cd->stackframesize * 8 - sizeof(stackframeinfo_t) +
3034 OFFSET(stackframeinfo_t, intregs);
3036 for (i = 0; i < INT_SAV_CNT; i++)
3037 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3040 M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
3041 M_MTLR(REG_ITMP2_XPC);
3042 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe */
3044 /* check for exception */
3046 M_TST(REG_ITMP1_XPTR);
3047 M_BNE(1); /* if no exception then return */
3051 /* handle exception */
3053 M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3055 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3056 M_ALD(REG_ITMP3, REG_PV, disp);
3063 * These are local overrides for various environment variables in Emacs.
3064 * Please do not remove this and leave it at the end of the file, where
3065 * Emacs will automagically detect them.
3066 * ---------------------------------------------------------------------
3069 * indent-tabs-mode: t
3073 * vim:noexpandtab:sw=4:ts=4: