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 && (m->flags & ACC_SYNCHRONIZED))
141 cd->stackframesize += 2;
144 /* create method header */
146 /* align stack to 16-bytes */
148 if (!jd->isleafmethod || JITDATA_HAS_FLAG_VERBOSECALL(jd))
149 ALIGN_2(cd->stackframesize);
151 else if (jd->isleafmethod && (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 #if defined(ENABLE_THREADS)
158 /* IsSync contains the offset relative to the stack pointer for the
159 argument of monitor_exit used in the exception handler. Since the
160 offset could be zero and give a wrong meaning of the flag it is
164 if (checksync && (m->flags & ACC_SYNCHRONIZED))
165 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8);/* IsSync */
168 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
170 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
171 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
172 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
174 dseg_addlinenumbertablesize(cd);
176 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
178 /* create exception table */
180 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
181 dseg_add_target(cd, ex->start);
182 dseg_add_target(cd, ex->end);
183 dseg_add_target(cd, ex->handler);
184 (void) dseg_add_unique_address(cd, ex->catchtype.any);
187 #if defined(ENABLE_PROFILING)
188 /* generate method profiling code */
190 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
191 /* count frequency */
193 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
194 M_ALD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
195 M_IADD_IMM(REG_ITMP2, 1, REG_ITMP2);
196 M_AST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
198 /* PROFILE_CYCLE_START; */
202 /* create stack frame (if necessary) */
204 if (!jd->isleafmethod) {
206 M_AST(REG_ZERO, REG_SP, LA_LR_OFFSET);
209 if (cd->stackframesize)
210 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
212 /* save return address and used callee saved registers */
214 p = cd->stackframesize;
215 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
216 p--; M_IST(rd->savintregs[i], REG_SP, p * 8);
218 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
219 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
222 /* take arguments out of register or stack frame */
226 for (p = 0, l = 0; p < md->paramcount; p++) {
227 t = md->paramtypes[p].type;
228 varindex = jd->local_map[l * 5 + t];
231 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
234 if (varindex == UNUSED)
238 s1 = md->params[p].regoff;
240 if (IS_INT_LNG_TYPE(t)) {
241 if (!md->params[p].inmemory) {
242 if (!IS_INMEMORY(var->flags)) {
243 if (IS_2_WORD_TYPE(t))
244 M_LNGMOVE(s1, var->vv.regoff);
246 M_INTMOVE(s1, var->vv.regoff);
249 if (IS_2_WORD_TYPE(t))
250 M_LST(s1, REG_SP, var->vv.regoff);
252 M_IST(s1, REG_SP, var->vv.regoff);
256 if (!IS_INMEMORY(var->flags)) {
257 if (IS_2_WORD_TYPE(t))
258 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
260 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
264 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1);
265 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
266 if (IS_2_WORD_TYPE(t)) {
267 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize * 8 + s1 + 4);
268 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
271 /* Reuse Memory Position on Caller Stack */
272 var->vv.regoff = cd->stackframesize * 8 + s1;
278 if (!md->params[p].inmemory) {
279 if (!IS_INMEMORY(var->flags))
280 M_FLTMOVE(s1, var->vv.regoff);
282 M_DST(s1, REG_SP, var->vv.regoff);
285 if (!IS_INMEMORY(var->flags))
286 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
289 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize * 8 + s1);
290 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
292 /* Reuse Memory Position on Caller Stack */
293 var->vv.regoff = cd->stackframesize * 8 + s1;
300 #if defined(ENABLE_THREADS)
301 /* call monitorenter function */
303 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
304 /* stack offset for monitor argument */
308 # if !defined(NDEBUG)
309 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
310 M_AADD_IMM(REG_SP, -((LA_SIZE_IN_POINTERS + ARG_CNT) * 8), REG_SP);
312 for (p = 0; p < INT_ARG_CNT; p++)
313 M_IST(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
315 for (p = 0; p < FLT_ARG_CNT; p++)
316 M_DST(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
318 s1 += LA_SIZE_IN_POINTERS + ARG_CNT;
322 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
323 M_ALD(REG_ITMP3, REG_PV, disp);
326 /* get or test the lock object */
328 if (m->flags & ACC_STATIC) {
329 disp = dseg_add_address(cd, &m->class->object.header);
330 M_ALD(REG_A0, REG_PV, disp);
335 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
338 M_AST(REG_A0, REG_SP, s1 * 8);
341 # if !defined(NDEBUG)
342 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
343 for (p = 0; p < INT_ARG_CNT; p++)
344 M_ILD(abi_registers_integer_argument[p], REG_SP, LA_SIZE + p * 8);
346 for (p = 0; p < FLT_ARG_CNT; p++)
347 M_DLD(abi_registers_float_argument[p], REG_SP, LA_SIZE + (INT_ARG_CNT + p) * 8);
349 M_AADD_IMM(REG_SP, (LA_SIZE_IN_POINTERS + ARG_CNT) * 8, REG_SP);
353 #endif /* defined(ENABLE_THREADS) */
355 /* call trace function */
357 emit_verbosecall_enter(jd);
360 /* end of header generation */
362 /* create replacement points */
364 REPLACEMENT_POINTS_INIT(cd, jd);
366 /* walk through all basic blocks */
368 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
370 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
372 if (bptr->flags >= BBREACHED) {
373 /* branch resolving */
375 codegen_resolve_branchrefs(cd, bptr);
377 /* handle replacement points */
379 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
381 #if defined(ENABLE_PROFILING)
382 /* generate basicblock profiling code */
384 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
385 /* count frequency */
387 disp = dseg_add_address(cd, code->bbfrequency);
388 M_ALD(REG_ITMP2, REG_PV, disp);
389 M_ALD(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
390 M_IADD_IMM(REG_ITMP3, 1, REG_ITMP3);
391 M_AST(REG_ITMP3, REG_ITMP2, bptr->nr * 4);
393 /* if this is an exception handler, start profiling again */
395 /* if (bptr->type == BBTYPE_EXH) */
396 /* PROFILE_CYCLE_START; */
400 /* copy interface registers to their destination */
405 #if defined(ENABLE_LSRA)
407 while (src != NULL) {
409 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
410 /* d = reg_of_var(m, src, REG_ITMP1); */
411 if (!IS_INMEMORY(src->flags))
415 M_INTMOVE(REG_ITMP1, d);
416 emit_store(jd, NULL, src, d);
424 var = VAR(bptr->invars[len]);
425 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
426 d = codegen_reg_of_var(0, var, REG_ITMP1);
427 M_INTMOVE(REG_ITMP1, d);
428 emit_store(jd, NULL, var, d);
431 assert((var->flags & INOUT));
435 #if defined(ENABLE_LSRA)
438 /* walk through all instructions */
443 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
444 if (iptr->line != currentline) {
445 dseg_addlinenumber(cd, iptr->line);
446 currentline = iptr->line;
449 MCODECHECK(64); /* an instruction usually needs < 64 words */
452 case ICMD_NOP: /* ... ==> ... */
453 case ICMD_POP: /* ..., value ==> ... */
454 case ICMD_POP2: /* ..., value, value ==> ... */
457 case ICMD_INLINE_START:
459 REPLACEMENT_POINT_INLINE_START(cd, iptr);
462 case ICMD_INLINE_BODY:
464 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
465 dseg_addlinenumber_inline_start(cd, iptr);
466 dseg_addlinenumber(cd, iptr->line);
469 case ICMD_INLINE_END:
471 dseg_addlinenumber_inline_end(cd, iptr);
472 dseg_addlinenumber(cd, iptr->line);
475 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
477 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
478 emit_nullpointer_check(cd, iptr, s1);
481 /* constant operations ************************************************/
483 case ICMD_ICONST: /* ... ==> ..., constant */
485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
486 ICONST(d, iptr->sx.val.i);
487 emit_store_dst(jd, iptr, d);
490 case ICMD_LCONST: /* ... ==> ..., constant */
492 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
493 LCONST(d, iptr->sx.val.l);
494 emit_store_dst(jd, iptr, d);
497 case ICMD_FCONST: /* ... ==> ..., constant */
499 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
500 a = dseg_add_float(cd, iptr->sx.val.f);
502 emit_store_dst(jd, iptr, d);
505 case ICMD_DCONST: /* ... ==> ..., constant */
507 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
508 a = dseg_add_double(cd, iptr->sx.val.d);
510 emit_store_dst(jd, iptr, d);
513 case ICMD_ACONST: /* ... ==> ..., constant */
515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
517 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
518 constant_classref *cr = iptr->sx.val.c.ref;;
520 disp = dseg_add_unique_address(cd, cr);
522 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
526 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
528 M_ALD(d, REG_PV, disp);
529 emit_store_dst(jd, iptr, d);
533 /* load/store/copy/move operations ************************************/
535 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
536 case ICMD_ALOAD: /* s1 = local variable */
540 case ICMD_ISTORE: /* ..., value ==> ... */
552 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
557 /* integer operations *************************************************/
559 case ICMD_INEG: /* ..., value ==> ..., - value */
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 emit_store_dst(jd, iptr, d);
567 case ICMD_LNEG: /* ..., value ==> ..., - value */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
571 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
572 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
573 emit_store_dst(jd, iptr, d);
576 case ICMD_I2L: /* ..., value ==> ..., value */
578 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
580 M_INTMOVE(s1, GET_LOW_REG(d));
581 M_SRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
582 emit_store_dst(jd, iptr, d);
585 case ICMD_L2I: /* ..., value ==> ..., value */
587 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
590 emit_store_dst(jd, iptr, d);
593 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
606 emit_store_dst(jd, iptr, d);
609 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
614 emit_store_dst(jd, iptr, d);
618 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
621 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
622 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
624 emit_store_dst(jd, iptr, d);
627 /* s1.localindex = variable, sx.val.i = constant*/
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
634 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
635 M_IADD_IMM(s1, iptr->sx.val.i, d);
637 ICONST(REG_ITMP2, iptr->sx.val.i);
638 M_IADD(s1, REG_ITMP2, d);
640 /* XXX the old code for ICMD_IINC was as follows:
642 u4 m = iptr->sx.val.i;
646 M_ADDIS(s1, m >> 16, d);
648 M_IADD_IMM(s1, m & 0xffff, d);
651 emit_store_dst(jd, iptr, d);
654 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
656 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
657 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
658 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
659 M_ADDC(s1, s2, GET_LOW_REG(d));
660 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
661 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
662 M_ADDE(s1, s2, GET_HIGH_REG(d));
663 emit_store_dst(jd, iptr, d);
666 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
667 /* sx.val.l = constant */
669 s3 = iptr->sx.val.l & 0xffffffff;
670 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
672 if ((s3 >= -32768) && (s3 <= 32767))
673 M_ADDIC(s1, s3, GET_LOW_REG(d));
675 ICONST(REG_ITMP2, s3);
676 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
678 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
679 s3 = iptr->sx.val.l >> 32;
681 M_ADDME(s1, GET_HIGH_REG(d));
683 M_ADDZE(s1, GET_HIGH_REG(d));
685 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
686 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
688 emit_store_dst(jd, iptr, d);
691 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
697 emit_store_dst(jd, iptr, d);
700 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
701 /* sx.val.i = constant */
703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
705 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
706 M_IADD_IMM(s1, -iptr->sx.val.i, d);
708 ICONST(REG_ITMP2, iptr->sx.val.i);
709 M_ISUB(s1, REG_ITMP2, d);
711 emit_store_dst(jd, iptr, d);
714 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
716 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
717 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
719 M_SUBC(s1, s2, GET_LOW_REG(d));
720 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
721 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
722 M_SUBE(s1, s2, GET_HIGH_REG(d));
723 emit_store_dst(jd, iptr, d);
726 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
727 /* sx.val.l = constant */
729 s3 = (-iptr->sx.val.l) & 0xffffffff;
730 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
732 if ((s3 >= -32768) && (s3 <= 32767)) {
733 M_ADDIC(s1, s3, GET_LOW_REG(d));
735 ICONST(REG_ITMP2, s3);
736 M_ADDC(s1, REG_ITMP2, GET_LOW_REG(d));
738 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
739 s3 = (-iptr->sx.val.l) >> 32;
741 M_ADDME(s1, GET_HIGH_REG(d));
743 M_ADDZE(s1, GET_HIGH_REG(d));
745 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
746 M_ADDE(s1, REG_ITMP3, GET_HIGH_REG(d));
748 emit_store_dst(jd, iptr, d);
751 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
756 emit_arithmetic_check(cd, iptr, s2);
757 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
758 M_CMP(REG_ITMP3, s1);
759 M_BNE(3 + (s1 != d));
761 M_BNE(1 + (s1 != d));
765 emit_store_dst(jd, iptr, d);
768 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
773 emit_arithmetic_check(cd, iptr, s2);
774 M_LDAH(REG_ITMP3, REG_ZERO, 0x8000);
775 M_CMP(REG_ITMP3, s1);
781 M_IDIV(s1, s2, REG_ITMP3);
782 M_IMUL(REG_ITMP3, s2, REG_ITMP3);
783 M_ISUB(s1, REG_ITMP3, d);
784 emit_store_dst(jd, iptr, d);
787 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
788 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
790 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
791 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
793 /* XXX TODO: only do this if arithmetic check is really done! */
794 M_OR_TST(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
795 /* XXX could be optimized */
796 emit_arithmetic_check(cd, iptr, REG_ITMP3);
798 bte = iptr->sx.s23.s3.bte;
799 disp = dseg_add_functionptr(cd, bte->fp);
800 M_ALD(REG_ITMP3, REG_PV, disp);
803 M_LNGMOVE(s1, REG_A0_A1_PACKED);
804 M_LNGMOVE(s2, REG_A2_A3_PACKED);
808 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
809 M_LNGMOVE(REG_RESULT_PACKED, d);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
815 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
816 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
819 emit_store_dst(jd, iptr, d);
822 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
823 /* sx.val.i = constant */
825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
828 M_IMUL_IMM(s1, iptr->sx.val.i, d);
830 ICONST(REG_ITMP3, iptr->sx.val.i);
831 M_IMUL(s1, REG_ITMP3, d);
833 emit_store_dst(jd, iptr, d);
836 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
840 M_SRA_IMM(s1, iptr->sx.val.i, d);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 M_AND_IMM(s2, 0x1f, REG_ITMP3);
851 M_SLL(s1, REG_ITMP3, d);
852 emit_store_dst(jd, iptr, d);
855 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
856 /* sx.val.i = constant */
858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
866 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
867 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869 M_AND_IMM(s2, 0x1f, REG_ITMP3);
870 M_SRA(s1, REG_ITMP3, d);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
875 /* sx.val.i = constant */
877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
887 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
888 M_AND_IMM(s2, 0x1f, REG_ITMP2);
889 M_SRL(s1, REG_ITMP2, d);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
894 /* sx.val.i = constant */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 if (iptr->sx.val.i & 0x1f)
899 M_SRL_IMM(s1, iptr->sx.val.i & 0x1f, d);
903 emit_store_dst(jd, iptr, d);
906 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
909 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
910 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
912 emit_store_dst(jd, iptr, d);
915 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
916 /* sx.val.i = constant */
918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
920 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
921 M_AND_IMM(s1, iptr->sx.val.i, d);
923 else if (iptr->sx.val.i == 0xffffff) {
924 M_RLWINM(s1, 0, 8, 31, d);
928 ICONST(REG_ITMP3, iptr->sx.val.i);
929 M_AND(s1, REG_ITMP3, d);
931 emit_store_dst(jd, iptr, d);
934 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
936 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
937 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
938 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
939 M_AND(s1, s2, GET_LOW_REG(d));
940 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
941 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
942 M_AND(s1, s2, GET_HIGH_REG(d));
943 emit_store_dst(jd, iptr, d);
946 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
947 /* sx.val.l = constant */
949 s3 = iptr->sx.val.l & 0xffffffff;
950 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
952 if ((s3 >= 0) && (s3 <= 65535))
953 M_AND_IMM(s1, s3, GET_LOW_REG(d));
955 ICONST(REG_ITMP3, s3);
956 M_AND(s1, REG_ITMP3, GET_LOW_REG(d));
958 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
959 s3 = iptr->sx.val.l >> 32;
960 if ((s3 >= 0) && (s3 <= 65535))
961 M_AND_IMM(s1, s3, GET_HIGH_REG(d));
963 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
964 M_AND(s1, REG_ITMP3, GET_HIGH_REG(d));
966 emit_store_dst(jd, iptr, d);
969 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
970 /* sx.val.i = constant */
972 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
973 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
974 M_MOV(s1, REG_ITMP2);
976 M_BGE(1 + 2*(iptr->sx.val.i >= 32768));
977 if (iptr->sx.val.i >= 32768) {
978 M_ADDIS(REG_ZERO, iptr->sx.val.i >> 16, REG_ITMP2);
979 M_OR_IMM(REG_ITMP2, iptr->sx.val.i, REG_ITMP2);
980 M_IADD(s1, REG_ITMP2, REG_ITMP2);
983 M_IADD_IMM(s1, iptr->sx.val.i, REG_ITMP2);
986 int b=0, m = iptr->sx.val.i;
989 M_RLWINM(REG_ITMP2, 0, 0, 30-b, REG_ITMP2);
991 M_ISUB(s1, REG_ITMP2, d);
992 emit_store_dst(jd, iptr, d);
995 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
998 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
999 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1001 emit_store_dst(jd, iptr, d);
1004 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1005 /* sx.val.i = constant */
1007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1008 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1009 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1010 M_OR_IMM(s1, iptr->sx.val.i, d);
1012 ICONST(REG_ITMP3, iptr->sx.val.i);
1013 M_OR(s1, REG_ITMP3, d);
1015 emit_store_dst(jd, iptr, d);
1018 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1020 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1021 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1022 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1023 M_OR(s1, s2, GET_LOW_REG(d));
1024 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1025 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1026 M_OR(s1, s2, GET_HIGH_REG(d));
1027 emit_store_dst(jd, iptr, d);
1030 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1031 /* sx.val.l = constant */
1033 s3 = iptr->sx.val.l & 0xffffffff;
1034 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1035 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1036 if ((s3 >= 0) && (s3 <= 65535))
1037 M_OR_IMM(s1, s3, GET_LOW_REG(d));
1039 ICONST(REG_ITMP3, s3);
1040 M_OR(s1, REG_ITMP3, GET_LOW_REG(d));
1042 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1043 s3 = iptr->sx.val.l >> 32;
1044 if ((s3 >= 0) && (s3 <= 65535))
1045 M_OR_IMM(s1, s3, GET_HIGH_REG(d));
1047 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1048 M_OR(s1, REG_ITMP3, GET_HIGH_REG(d));
1050 emit_store_dst(jd, iptr, d);
1053 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1055 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1056 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1057 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1059 emit_store_dst(jd, iptr, d);
1062 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1063 /* sx.val.i = constant */
1065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1066 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1067 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 65535))
1068 M_XOR_IMM(s1, iptr->sx.val.i, d);
1070 ICONST(REG_ITMP3, iptr->sx.val.i);
1071 M_XOR(s1, REG_ITMP3, d);
1073 emit_store_dst(jd, iptr, d);
1076 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1078 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1079 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1080 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1081 M_XOR(s1, s2, GET_LOW_REG(d));
1082 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1083 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);/* don't use REG_ITMP2*/
1084 M_XOR(s1, s2, GET_HIGH_REG(d));
1085 emit_store_dst(jd, iptr, d);
1088 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1089 /* sx.val.l = constant */
1091 s3 = iptr->sx.val.l & 0xffffffff;
1092 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1094 if ((s3 >= 0) && (s3 <= 65535))
1095 M_XOR_IMM(s1, s3, GET_LOW_REG(d));
1097 ICONST(REG_ITMP3, s3);
1098 M_XOR(s1, REG_ITMP3, GET_LOW_REG(d));
1100 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1101 s3 = iptr->sx.val.l >> 32;
1102 if ((s3 >= 0) && (s3 <= 65535))
1103 M_XOR_IMM(s1, s3, GET_HIGH_REG(d));
1105 ICONST(REG_ITMP3, s3); /* don't use REG_ITMP2 */
1106 M_XOR(s1, REG_ITMP3, GET_HIGH_REG(d));
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1113 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1114 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1115 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1116 vm_abort("codegen: implement ICMD_LCMP!");
1117 emit_store_dst(jd, iptr, d);
1121 /* floating operations ************************************************/
1123 case ICMD_FNEG: /* ..., value ==> ..., - value */
1125 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1126 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1128 emit_store_dst(jd, iptr, d);
1131 case ICMD_DNEG: /* ..., value ==> ..., - value */
1133 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1134 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1136 emit_store_dst(jd, iptr, d);
1139 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1141 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1142 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1143 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1145 emit_store_dst(jd, iptr, d);
1148 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1150 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1151 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1152 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1154 emit_store_dst(jd, iptr, d);
1157 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1159 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1160 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1161 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1163 emit_store_dst(jd, iptr, d);
1166 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1168 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1169 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1170 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1177 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1178 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1179 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1181 emit_store_dst(jd, iptr, d);
1184 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1186 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1187 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1188 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1195 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1197 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1199 emit_store_dst(jd, iptr, d);
1202 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1204 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1205 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1206 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1208 emit_store_dst(jd, iptr, d);
1211 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1214 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1215 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1217 disp = dseg_add_float(cd, 0.0);
1218 M_FLD(REG_FTMP2, REG_PV, disp);
1219 M_FCMPU(s1, REG_FTMP2);
1221 disp = dseg_add_unique_s4(cd, 0);
1222 M_CVTDL_C(s1, REG_FTMP1);
1223 M_LDA(REG_ITMP1, REG_PV, disp);
1224 M_STFIWX(REG_FTMP1, 0, REG_ITMP1);
1225 M_ILD(d, REG_PV, disp);
1226 emit_store_dst(jd, iptr, d);
1229 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1231 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1232 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1234 emit_store_dst(jd, iptr, d);
1237 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1239 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1240 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1246 case ICMD_DCMPL: /* == => 0, < => 1, > => -1 */
1249 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1250 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1251 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1253 M_IADD_IMM(REG_ZERO, -1, d);
1256 M_IADD_IMM(REG_ZERO, 0, d);
1258 M_IADD_IMM(REG_ZERO, 1, d);
1259 emit_store_dst(jd, iptr, d);
1262 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1263 case ICMD_DCMPG: /* == => 0, < => 1, > => -1 */
1265 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1266 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1267 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1269 M_IADD_IMM(REG_ZERO, 1, d);
1272 M_IADD_IMM(REG_ZERO, 0, d);
1274 M_IADD_IMM(REG_ZERO, -1, d);
1275 emit_store_dst(jd, iptr, d);
1278 case ICMD_IF_FCMPEQ: /* ..., value, value ==> ... */
1279 case ICMD_IF_DCMPEQ:
1281 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1282 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1285 emit_beq(cd, iptr->dst.block);
1288 case ICMD_IF_FCMPNE: /* ..., value, value ==> ... */
1289 case ICMD_IF_DCMPNE:
1291 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1292 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 emit_bnan(cd, iptr->dst.block);
1295 emit_bne(cd, iptr->dst.block);
1299 case ICMD_IF_FCMPL_LT: /* ..., value, value ==> ... */
1300 case ICMD_IF_DCMPL_LT:
1302 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1303 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1305 emit_bnan(cd, iptr->dst.block);
1306 emit_blt(cd, iptr->dst.block);
1309 case ICMD_IF_FCMPL_GT: /* ..., value, value ==> ... */
1310 case ICMD_IF_DCMPL_GT:
1312 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1313 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1316 emit_bgt(cd, iptr->dst.block);
1319 case ICMD_IF_FCMPL_LE: /* ..., value, value ==> ... */
1320 case ICMD_IF_DCMPL_LE:
1322 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1323 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1325 emit_bnan(cd, iptr->dst.block);
1326 emit_ble(cd, iptr->dst.block);
1329 case ICMD_IF_FCMPL_GE: /* ..., value, value ==> ... */
1330 case ICMD_IF_DCMPL_GE:
1332 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1333 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1336 emit_bge(cd, iptr->dst.block);
1339 case ICMD_IF_FCMPG_LT: /* ..., value, value ==> ... */
1340 case ICMD_IF_DCMPG_LT:
1342 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1343 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1346 emit_blt(cd, iptr->dst.block);
1349 case ICMD_IF_FCMPG_GT: /* ..., value, value ==> ... */
1350 case ICMD_IF_DCMPG_GT:
1352 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1353 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1355 emit_bnan(cd, iptr->dst.block);
1356 emit_bgt(cd, iptr->dst.block);
1359 case ICMD_IF_FCMPG_LE: /* ..., value, value ==> ... */
1360 case ICMD_IF_DCMPG_LE:
1362 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1363 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1366 emit_ble(cd, iptr->dst.block);
1369 case ICMD_IF_FCMPG_GE: /* ..., value, value ==> ... */
1370 case ICMD_IF_DCMPG_GE:
1372 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1373 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1375 emit_bnan(cd, iptr->dst.block);
1376 emit_bge(cd, iptr->dst.block);
1380 /* memory operations **************************************************/
1382 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1386 /* implicit null-pointer check */
1387 M_ILD(d, s1, OFFSET(java_array_t, size));
1388 emit_store_dst(jd, iptr, d);
1391 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1393 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1394 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1396 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1397 M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1398 /* implicit null-pointer check */
1399 M_LBZX(d, s1, REG_ITMP2);
1401 emit_store_dst(jd, iptr, d);
1404 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1407 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1408 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1409 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1410 M_SLL_IMM(s2, 1, REG_ITMP2);
1411 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1412 /* implicit null-pointer check */
1413 M_LHZX(d, s1, REG_ITMP2);
1414 emit_store_dst(jd, iptr, d);
1417 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1420 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1421 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1422 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1423 M_SLL_IMM(s2, 1, REG_ITMP2);
1424 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1425 /* implicit null-pointer check */
1426 M_LHAX(d, s1, REG_ITMP2);
1427 emit_store_dst(jd, iptr, d);
1430 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1435 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1436 M_SLL_IMM(s2, 2, REG_ITMP2);
1437 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1438 /* implicit null-pointer check */
1439 M_LWZX(d, s1, REG_ITMP2);
1440 emit_store_dst(jd, iptr, d);
1443 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1446 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1448 /* implicit null-pointer check */
1449 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1450 M_SLL_IMM(s2, 3, REG_ITMP2);
1451 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1452 M_LLD_INTERN(d, REG_ITMP2, OFFSET(java_longarray_t, data[0]));
1453 emit_store_dst(jd, iptr, d);
1456 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1458 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1459 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1460 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1461 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1462 M_SLL_IMM(s2, 2, REG_ITMP2);
1463 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1464 /* implicit null-pointer check */
1465 M_LFSX(d, s1, REG_ITMP2);
1466 emit_store_dst(jd, iptr, d);
1469 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1471 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1472 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1473 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1474 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1475 M_SLL_IMM(s2, 3, REG_ITMP2);
1476 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1477 /* implicit null-pointer check */
1478 M_LFDX(d, s1, REG_ITMP2);
1479 emit_store_dst(jd, iptr, d);
1482 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1487 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1488 M_SLL_IMM(s2, 2, REG_ITMP2);
1489 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1490 /* implicit null-pointer check */
1491 M_LWZX(d, s1, REG_ITMP2);
1492 emit_store_dst(jd, iptr, d);
1496 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1499 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1500 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1502 M_IADD_IMM(s2, OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1503 /* implicit null-pointer check */
1504 M_STBX(s3, s1, REG_ITMP2);
1507 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1510 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1511 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1512 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1513 M_SLL_IMM(s2, 1, REG_ITMP2);
1514 M_IADD_IMM(REG_ITMP2, OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1515 /* implicit null-pointer check */
1516 M_STHX(s3, s1, REG_ITMP2);
1519 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1523 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1524 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1525 M_SLL_IMM(s2, 1, REG_ITMP2);
1526 M_IADD_IMM(REG_ITMP2, OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1527 /* implicit null-pointer check */
1528 M_STHX(s3, s1, REG_ITMP2);
1531 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1533 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1534 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1535 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1536 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1537 M_SLL_IMM(s2, 2, REG_ITMP2);
1538 M_IADD_IMM(REG_ITMP2, OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1539 /* implicit null-pointer check */
1540 M_STWX(s3, s1, REG_ITMP2);
1543 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1546 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1547 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1548 s3 = emit_load_s3_high(jd, iptr, REG_ITMP3);
1549 M_SLL_IMM(s2, 3, REG_ITMP2);
1550 M_IADD_IMM(REG_ITMP2, OFFSET(java_longarray_t, data[0]), REG_ITMP2);
1551 /* implicit null-pointer check */
1552 M_STWX(s3, s1, REG_ITMP2);
1553 M_IADD_IMM(REG_ITMP2, 4, REG_ITMP2);
1554 s3 = emit_load_s3_low(jd, iptr, REG_ITMP3);
1555 M_STWX(s3, s1, REG_ITMP2);
1558 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1561 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1562 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1563 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1564 M_SLL_IMM(s2, 2, REG_ITMP2);
1565 M_IADD_IMM(REG_ITMP2, OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1566 /* implicit null-pointer check */
1567 M_STFSX(s3, s1, REG_ITMP2);
1570 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1573 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1574 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1575 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1576 M_SLL_IMM(s2, 3, REG_ITMP2);
1577 M_IADD_IMM(REG_ITMP2, OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1578 /* implicit null-pointer check */
1579 M_STFDX(s3, s1, REG_ITMP2);
1582 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1584 s1 = emit_load_s1(jd, iptr, REG_A0);
1585 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1586 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1587 s3 = emit_load_s3(jd, iptr, REG_A1);
1589 /* XXX what if array is NULL */
1590 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1591 M_ALD(REG_ITMP3, REG_PV, disp);
1594 M_INTMOVE(s1, REG_A0);
1595 M_INTMOVE(s3, REG_A1);
1598 emit_exception_check(cd, iptr);
1600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1602 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1603 M_SLL_IMM(s2, 2, REG_ITMP2);
1604 M_IADD_IMM(REG_ITMP2, OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1605 /* implicit null-pointer check */
1606 M_STWX(s3, s1, REG_ITMP2);
1610 case ICMD_GETSTATIC: /* ... ==> ..., value */
1612 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1613 uf = iptr->sx.s23.s3.uf;
1614 fieldtype = uf->fieldref->parseddesc.fd->type;
1615 disp = dseg_add_unique_address(cd, uf);
1617 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1620 fi = iptr->sx.s23.s3.fmiref->p.field;
1621 fieldtype = fi->type;
1622 disp = dseg_add_address(cd, fi->value);
1624 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1625 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1629 M_ALD(REG_ITMP1, REG_PV, disp);
1630 switch (fieldtype) {
1632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1633 M_ILD_INTERN(d, REG_ITMP1, 0);
1636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1637 M_ILD_INTERN(GET_LOW_REG(d), REG_ITMP1, 4);/* keep this order */
1638 M_ILD_INTERN(GET_HIGH_REG(d), REG_ITMP1, 0);/*keep this order */
1641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1642 M_ALD_INTERN(d, REG_ITMP1, 0);
1645 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1646 M_FLD_INTERN(d, REG_ITMP1, 0);
1649 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1650 M_DLD_INTERN(d, REG_ITMP1, 0);
1653 emit_store_dst(jd, iptr, d);
1656 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1658 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1659 uf = iptr->sx.s23.s3.uf;
1660 fieldtype = uf->fieldref->parseddesc.fd->type;
1661 disp = dseg_add_unique_address(cd, uf);
1663 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1666 fi = iptr->sx.s23.s3.fmiref->p.field;
1667 fieldtype = fi->type;
1668 disp = dseg_add_address(cd, fi->value);
1670 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1671 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1675 M_ALD(REG_ITMP1, REG_PV, disp);
1676 switch (fieldtype) {
1678 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1679 M_IST_INTERN(s1, REG_ITMP1, 0);
1682 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1683 M_LST_INTERN(s1, REG_ITMP1, 0);
1686 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1687 M_AST_INTERN(s1, REG_ITMP1, 0);
1690 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1691 M_FST_INTERN(s1, REG_ITMP1, 0);
1694 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1695 M_DST_INTERN(s1, REG_ITMP1, 0);
1701 case ICMD_GETFIELD: /* ... ==> ..., value */
1703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1705 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1706 uf = iptr->sx.s23.s3.uf;
1707 fieldtype = uf->fieldref->parseddesc.fd->type;
1710 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1713 fi = iptr->sx.s23.s3.fmiref->p.field;
1714 fieldtype = fi->type;
1718 /* implicit null-pointer check */
1719 switch (fieldtype) {
1721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1726 if (GET_HIGH_REG(d) == s1) {
1727 M_ILD(GET_LOW_REG(d), s1, disp + 4);
1728 M_ILD(GET_HIGH_REG(d), s1, disp);
1731 M_ILD(GET_HIGH_REG(d), s1, disp);
1732 M_ILD(GET_LOW_REG(d), s1, disp + 4);
1736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1740 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1744 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1748 emit_store_dst(jd, iptr, d);
1751 case ICMD_PUTFIELD: /* ..., value ==> ... */
1753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1755 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1756 uf = iptr->sx.s23.s3.uf;
1757 fieldtype = uf->fieldref->parseddesc.fd->type;
1761 fi = iptr->sx.s23.s3.fmiref->p.field;
1762 fieldtype = fi->type;
1766 if (IS_INT_LNG_TYPE(fieldtype)) {
1767 if (IS_2_WORD_TYPE(fieldtype))
1768 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1770 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1773 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1775 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1776 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1778 /* implicit null-pointer check */
1779 switch (fieldtype) {
1781 M_IST(s2, s1, disp);
1784 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
1785 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
1788 M_AST(s2, s1, disp);
1791 M_FST(s2, s1, disp);
1794 M_DST(s2, s1, disp);
1800 /* branch operations **************************************************/
1802 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805 M_INTMOVE(s1, REG_ITMP1_XPTR);
1807 #ifdef ENABLE_VERIFIER
1808 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1809 unresolved_class *uc = iptr->sx.s23.s2.uc;
1811 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1813 #endif /* ENABLE_VERIFIER */
1815 disp = dseg_add_functionptr(cd, asm_handle_exception);
1816 M_ALD(REG_ITMP2, REG_PV, disp);
1819 if (jd->isleafmethod)
1820 M_MFLR(REG_ITMP3); /* save LR */
1822 M_BL(0); /* get current PC */
1823 M_MFLR(REG_ITMP2_XPC);
1825 if (jd->isleafmethod)
1826 M_MTLR(REG_ITMP3); /* restore LR */
1828 M_RTS; /* jump to CTR */
1832 case ICMD_GOTO: /* ... ==> ... */
1833 case ICMD_RET: /* ... ==> ... */
1835 emit_br(cd, iptr->dst.block);
1839 case ICMD_JSR: /* ... ==> ... */
1841 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1845 case ICMD_IFNULL: /* ..., value ==> ... */
1846 case ICMD_IFNONNULL:
1848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1850 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1858 case ICMD_IFEQ: /* ..., value ==> ... */
1860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1861 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
1862 M_CMPI(s1, iptr->sx.val.i);
1864 ICONST(REG_ITMP2, iptr->sx.val.i);
1865 M_CMP(s1, REG_ITMP2);
1867 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1871 case ICMD_IF_LEQ: /* ..., value ==> ... */
1873 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1874 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1875 if (iptr->sx.val.l == 0) {
1876 M_OR_TST(s1, s2, REG_ITMP3);
1878 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1879 M_XOR_IMM(s2, 0, REG_ITMP2);
1880 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1881 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1884 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1885 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1886 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1887 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1888 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1890 emit_beq(cd, iptr->dst.block);
1893 case ICMD_IF_LLT: /* ..., value ==> ... */
1895 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1896 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1897 if (iptr->sx.val.l == 0) {
1898 /* if high word is less than zero, the whole long is too */
1900 emit_blt(cd, iptr->dst.block);
1902 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1904 emit_blt(cd, iptr->dst.block);
1905 emit_label_bgt(cd, BRANCH_LABEL_1);
1906 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1907 emit_blt(cd, iptr->dst.block);
1908 emit_label(cd, BRANCH_LABEL_1);
1911 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1912 M_CMP(s2, REG_ITMP3);
1913 emit_blt(cd, iptr->dst.block);
1914 emit_label_bgt(cd, BRANCH_LABEL_1);
1915 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1916 M_CMPU(s1, REG_ITMP3);
1917 emit_blt(cd, iptr->dst.block);
1918 emit_label(cd, BRANCH_LABEL_1);
1922 case ICMD_IF_LLE: /* ..., value ==> ... */
1924 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1925 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1926 /* if (iptr->sx.val.l == 0) { */
1927 /* M_OR(s1, s2, REG_ITMP3); */
1928 /* M_CMPI(REG_ITMP3, 0); */
1931 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1933 emit_blt(cd, iptr->dst.block);
1934 emit_label_bgt(cd, BRANCH_LABEL_1);
1935 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1938 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1939 M_CMP(s2, REG_ITMP3);
1940 emit_blt(cd, iptr->dst.block);
1941 emit_label_bgt(cd, BRANCH_LABEL_1);
1942 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1943 M_CMPU(s1, REG_ITMP3);
1945 emit_ble(cd, iptr->dst.block);
1946 emit_label(cd, BRANCH_LABEL_1);
1949 case ICMD_IF_LNE: /* ..., value ==> ... */
1951 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1952 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1953 if (iptr->sx.val.l == 0) {
1954 M_OR_TST(s1, s2, REG_ITMP3);
1956 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1957 M_XOR_IMM(s2, 0, REG_ITMP2);
1958 M_XOR_IMM(s1, iptr->sx.val.l & 0xffff, REG_ITMP1);
1959 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1962 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1963 M_XOR(s1, REG_ITMP3, REG_ITMP1);
1964 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1965 M_XOR(s2, REG_ITMP3, REG_ITMP2);
1966 M_OR_TST(REG_ITMP1, REG_ITMP2, REG_ITMP3);
1968 emit_bne(cd, iptr->dst.block);
1971 case ICMD_IF_LGT: /* ..., value ==> ... */
1973 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1974 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1975 /* if (iptr->sx.val.l == 0) { */
1976 /* M_OR(s1, s2, REG_ITMP3); */
1977 /* M_CMPI(REG_ITMP3, 0); */
1980 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1982 emit_bgt(cd, iptr->dst.block);
1983 emit_label_blt(cd, BRANCH_LABEL_1);
1984 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
1987 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
1988 M_CMP(s2, REG_ITMP3);
1989 emit_bgt(cd, iptr->dst.block);
1990 emit_label_blt(cd, BRANCH_LABEL_1);
1991 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
1992 M_CMPU(s1, REG_ITMP3);
1994 emit_bgt(cd, iptr->dst.block);
1995 emit_label(cd, BRANCH_LABEL_1);
1998 case ICMD_IF_LGE: /* ..., value ==> ... */
2000 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2001 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
2002 if (iptr->sx.val.l == 0) {
2003 /* if high word is greater equal zero, the whole long is too */
2005 emit_bge(cd, iptr->dst.block);
2007 else if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
2009 emit_bgt(cd, iptr->dst.block);
2010 emit_label_blt(cd, BRANCH_LABEL_1);
2011 M_CMPUI(s1, iptr->sx.val.l & 0xffff);
2012 emit_bge(cd, iptr->dst.block);
2013 emit_label(cd, BRANCH_LABEL_1);
2016 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
2017 M_CMP(s2, REG_ITMP3);
2018 emit_bgt(cd, iptr->dst.block);
2019 emit_label_blt(cd, BRANCH_LABEL_1);
2020 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2021 M_CMPU(s1, REG_ITMP3);
2022 emit_bge(cd, iptr->dst.block);
2023 emit_label(cd, BRANCH_LABEL_1);
2027 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2028 case ICMD_IF_ICMPNE:
2029 case ICMD_IF_ICMPLT:
2030 case ICMD_IF_ICMPGT:
2031 case ICMD_IF_ICMPLE:
2032 case ICMD_IF_ICMPGE:
2034 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2035 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2037 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
2040 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2041 case ICMD_IF_ACMPNE:
2043 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2044 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2046 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
2049 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2051 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2052 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2054 emit_label_bne(cd, BRANCH_LABEL_1);
2055 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2056 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2058 emit_beq(cd, iptr->dst.block);
2059 emit_label(cd, BRANCH_LABEL_1);
2062 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2064 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2065 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2067 emit_bne(cd, iptr->dst.block);
2068 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2069 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2071 emit_bne(cd, iptr->dst.block);
2074 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2076 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2077 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2079 emit_blt(cd, iptr->dst.block);
2080 emit_label_bgt(cd, BRANCH_LABEL_1);
2081 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2082 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2084 emit_blt(cd, iptr->dst.block);
2085 emit_label(cd, BRANCH_LABEL_1);
2088 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2090 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2091 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2093 emit_bgt(cd, iptr->dst.block);
2094 emit_label_blt(cd, BRANCH_LABEL_1);
2095 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2096 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2098 emit_bgt(cd, iptr->dst.block);
2099 emit_label(cd, BRANCH_LABEL_1);
2102 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2104 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2105 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2107 emit_blt(cd, iptr->dst.block);
2108 emit_label_bgt(cd, BRANCH_LABEL_1);
2109 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2110 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2112 emit_ble(cd, iptr->dst.block);
2113 emit_label(cd, BRANCH_LABEL_1);
2116 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2118 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2119 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2121 emit_bgt(cd, iptr->dst.block);
2122 emit_label_blt(cd, BRANCH_LABEL_1);
2123 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2124 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2126 emit_bge(cd, iptr->dst.block);
2127 emit_label(cd, BRANCH_LABEL_1);
2130 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2132 REPLACEMENT_POINT_RETURN(cd, iptr);
2133 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2134 M_INTMOVE(s1, REG_RESULT);
2135 goto nowperformreturn;
2137 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2139 REPLACEMENT_POINT_RETURN(cd, iptr);
2140 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2141 M_INTMOVE(s1, REG_RESULT);
2143 #ifdef ENABLE_VERIFIER
2144 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2145 unresolved_class *uc = iptr->sx.s23.s2.uc;
2147 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2149 #endif /* ENABLE_VERIFIER */
2150 goto nowperformreturn;
2152 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2154 REPLACEMENT_POINT_RETURN(cd, iptr);
2155 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2156 M_LNGMOVE(s1, REG_RESULT_PACKED);
2157 goto nowperformreturn;
2159 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2162 REPLACEMENT_POINT_RETURN(cd, iptr);
2163 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2164 M_FLTMOVE(s1, REG_FRESULT);
2165 goto nowperformreturn;
2167 case ICMD_RETURN: /* ... ==> ... */
2169 REPLACEMENT_POINT_RETURN(cd, iptr);
2175 p = cd->stackframesize;
2177 /* call trace function */
2179 emit_verbosecall_exit(jd);
2181 #if defined(ENABLE_THREADS)
2182 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2183 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2184 M_ALD(REG_ITMP3, REG_PV, disp);
2187 /* we need to save the proper return value */
2189 switch (iptr->opc) {
2191 M_IST(REG_RESULT2, REG_SP, rd->memuse * 8 + 8);
2195 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 4);
2199 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 4);
2203 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2206 /* and now restore the proper return value */
2208 switch (iptr->opc) {
2210 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 8 + 8);
2214 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 4);
2218 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 4);
2224 /* restore return address */
2226 if (!jd->isleafmethod) {
2227 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
2228 may have a displacement overflow. */
2230 M_ALD(REG_ITMP1, REG_SP, p * 8 + LA_LR_OFFSET);
2234 /* restore saved registers */
2236 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2237 p--; M_ILD(rd->savintregs[i], REG_SP, p * 8);
2239 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2240 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2243 /* deallocate stack */
2245 if (cd->stackframesize)
2246 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2254 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2257 branch_target_t *table;
2259 table = iptr->dst.table;
2261 l = iptr->sx.s23.s2.tablelow;
2262 i = iptr->sx.s23.s3.tablehigh;
2264 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2266 M_INTMOVE(s1, REG_ITMP1);
2267 else if (l <= 32768)
2268 M_LDA(REG_ITMP1, s1, -l);
2270 ICONST(REG_ITMP2, l);
2271 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2278 M_CMPUI(REG_ITMP1, i - 1);
2279 emit_bgt(cd, table[0].block);
2281 /* build jump table top down and use address of lowest entry */
2286 dseg_add_target(cd, table->block);
2290 /* length of dataseg after last dseg_add_target is used by load */
2292 M_SLL_IMM(REG_ITMP1, 2, REG_ITMP1);
2293 M_IADD(REG_ITMP1, REG_PV, REG_ITMP2);
2294 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2302 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2305 lookup_target_t *lookup;
2307 lookup = iptr->dst.lookup;
2309 i = iptr->sx.s23.s2.lookupcount;
2311 MCODECHECK((i<<2)+8);
2312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2315 if ((lookup->value >= -32768) && (lookup->value <= 32767)) {
2316 M_CMPI(s1, lookup->value);
2319 disp = dseg_add_s4(cd, lookup->value);
2320 M_ILD(REG_ITMP2, REG_PV, disp);
2321 M_CMP(s1, REG_ITMP2);
2323 emit_beq(cd, lookup->target.block);
2327 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2333 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2335 bte = iptr->sx.s23.s3.bte;
2339 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2341 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2342 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2343 case ICMD_INVOKEINTERFACE:
2345 REPLACEMENT_POINT_INVOKE(cd, iptr);
2347 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2349 um = iptr->sx.s23.s3.um;
2350 md = um->methodref->parseddesc.md;
2353 lm = iptr->sx.s23.s3.fmiref->p.method;
2355 md = lm->parseddesc;
2359 s3 = md->paramcount;
2361 MCODECHECK((s3 << 1) + 64);
2363 /* copy arguments to registers or stack location */
2365 for (s3 = s3 - 1; s3 >= 0; s3--) {
2366 var = VAR(iptr->sx.s23.s2.args[s3]);
2367 d = md->params[s3].regoff;
2369 /* Already Preallocated? */
2370 if (var->flags & PREALLOC)
2373 if (IS_INT_LNG_TYPE(var->type)) {
2374 if (!md->params[s3].inmemory) {
2375 if (IS_2_WORD_TYPE(var->type)) {
2376 s1 = emit_load(jd, iptr, var, d);
2380 s1 = emit_load(jd, iptr, var, d);
2385 if (IS_2_WORD_TYPE(var->type)) {
2386 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2387 M_LST(s1, REG_SP, d);
2390 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2391 M_IST(s1, REG_SP, d);
2396 if (!md->params[s3].inmemory) {
2397 s1 = emit_load(jd, iptr, var, d);
2401 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2402 M_DST(s1, REG_SP, d);
2407 switch (iptr->opc) {
2409 disp = dseg_add_functionptr(cd, bte->fp);
2411 M_ALD(REG_PV, REG_PV, disp); /* pointer to built-in-function */
2413 /* generate the actual call */
2417 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2418 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2420 M_LDA(REG_PV, REG_ITMP1, -disp);
2422 emit_exception_check(cd, iptr);
2425 case ICMD_INVOKESPECIAL:
2426 emit_nullpointer_check(cd, iptr, REG_A0);
2429 case ICMD_INVOKESTATIC:
2431 disp = dseg_add_unique_address(cd, um);
2433 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2437 disp = dseg_add_address(cd, lm->stubroutine);
2439 M_ALD(REG_PV, REG_PV, disp);
2441 /* generate the actual call */
2445 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2446 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2448 M_LDA(REG_PV, REG_ITMP1, -disp);
2451 case ICMD_INVOKEVIRTUAL:
2453 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2458 s1 = OFFSET(vftbl_t, table[0]) +
2459 sizeof(methodptr) * lm->vftblindex;
2462 /* implicit null-pointer check */
2463 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2464 M_ALD(REG_PV, REG_METHODPTR, s1);
2466 /* generate the actual call */
2470 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2471 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2473 M_LDA(REG_PV, REG_ITMP1, -disp);
2476 case ICMD_INVOKEINTERFACE:
2478 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2484 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2485 sizeof(methodptr*) * lm->class->index;
2487 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2490 /* implicit null-pointer check */
2491 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2492 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2493 M_ALD(REG_PV, REG_METHODPTR, s2);
2495 /* generate the actual call */
2499 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2500 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2502 M_LDA(REG_PV, REG_ITMP1, -disp);
2506 /* store return value */
2508 d = md->returntype.type;
2510 if (d != TYPE_VOID) {
2511 if (IS_INT_LNG_TYPE(d)) {
2512 if (IS_2_WORD_TYPE(d)) {
2513 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
2514 M_LNGMOVE(REG_RESULT_PACKED, s1);
2517 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2518 M_INTMOVE(REG_RESULT, s1);
2522 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2523 M_FLTMOVE(REG_FRESULT, s1);
2525 emit_store_dst(jd, iptr, s1);
2530 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2532 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2533 /* object type cast-check */
2538 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2543 super = iptr->sx.s23.s3.c.cls;
2544 superindex = super->index;
2547 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2548 CODEGEN_CRITICAL_SECTION_NEW;
2550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2552 /* if class is not resolved, check which code to call */
2554 if (super == NULL) {
2556 emit_label_beq(cd, BRANCH_LABEL_1);
2558 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2560 patcher_add_patch_ref(jd,
2561 PATCHER_resolve_classref_to_flags,
2562 iptr->sx.s23.s3.c.ref,
2565 M_ILD(REG_ITMP2, REG_PV, disp);
2566 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2567 emit_label_beq(cd, BRANCH_LABEL_2);
2570 /* interface checkcast code */
2572 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2573 if (super == NULL) {
2574 patcher_add_patch_ref(jd,
2575 PATCHER_checkcast_interface,
2576 iptr->sx.s23.s3.c.ref,
2581 emit_label_beq(cd, BRANCH_LABEL_3);
2584 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2585 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2586 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2587 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2589 M_ALD(REG_ITMP3, REG_ITMP2,
2590 OFFSET(vftbl_t, interfacetable[0]) -
2591 superindex * sizeof(methodptr*));
2593 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2596 emit_label_br(cd, BRANCH_LABEL_4);
2598 emit_label(cd, BRANCH_LABEL_3);
2601 /* class checkcast code */
2603 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2604 if (super == NULL) {
2605 emit_label(cd, BRANCH_LABEL_2);
2607 disp = dseg_add_unique_address(cd, NULL);
2609 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2610 iptr->sx.s23.s3.c.ref,
2614 disp = dseg_add_address(cd, super->vftbl);
2617 emit_label_beq(cd, BRANCH_LABEL_5);
2620 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2622 CODEGEN_CRITICAL_SECTION_START;
2624 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2625 M_ALD(REG_ITMP2, REG_PV, disp);
2626 if (s1 != REG_ITMP1) {
2627 M_ILD(REG_ITMP1, REG_ITMP2, OFFSET(vftbl_t, baseval));
2628 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2630 CODEGEN_CRITICAL_SECTION_END;
2632 M_ISUB(REG_ITMP3, REG_ITMP1, REG_ITMP3);
2635 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2636 M_ISUB(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2637 M_ALD(REG_ITMP2, REG_PV, disp);
2638 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2640 CODEGEN_CRITICAL_SECTION_END;
2642 M_CMPU(REG_ITMP3, REG_ITMP2);
2643 emit_classcast_check(cd, iptr, BRANCH_GT, REG_ITMP3, s1);
2646 emit_label(cd, BRANCH_LABEL_5);
2649 if (super == NULL) {
2650 emit_label(cd, BRANCH_LABEL_1);
2651 emit_label(cd, BRANCH_LABEL_4);
2654 d = codegen_reg_of_dst(jd, iptr, s1);
2657 /* array type cast-check */
2659 s1 = emit_load_s1(jd, iptr, REG_A0);
2660 M_INTMOVE(s1, REG_A0);
2662 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2663 disp = dseg_add_unique_address(cd, NULL);
2665 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2666 iptr->sx.s23.s3.c.ref,
2670 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2672 M_ALD(REG_A1, REG_PV, disp);
2673 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2674 M_ALD(REG_ITMP2, REG_PV, disp);
2678 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2680 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2681 d = codegen_reg_of_dst(jd, iptr, s1);
2684 emit_store_dst(jd, iptr, d);
2687 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2693 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2698 super = iptr->sx.s23.s3.c.cls;
2699 superindex = super->index;
2702 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2703 CODEGEN_CRITICAL_SECTION_NEW;
2705 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2709 M_MOV(s1, REG_ITMP1);
2715 /* if class is not resolved, check which code to call */
2717 if (super == NULL) {
2719 emit_label_beq(cd, BRANCH_LABEL_1);
2721 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2723 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2724 iptr->sx.s23.s3.c.ref, disp);
2726 M_ILD(REG_ITMP3, REG_PV, disp);
2727 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2728 emit_label_beq(cd, BRANCH_LABEL_2);
2731 /* interface instanceof code */
2733 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2734 if (super == NULL) {
2735 patcher_add_patch_ref(jd,
2736 PATCHER_instanceof_interface,
2737 iptr->sx.s23.s3.c.ref, 0);
2741 emit_label_beq(cd, BRANCH_LABEL_3);
2744 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2745 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2746 M_LDATST(REG_ITMP3, REG_ITMP3, -superindex);
2748 M_ALD(REG_ITMP1, REG_ITMP1,
2749 OFFSET(vftbl_t, interfacetable[0]) -
2750 superindex * sizeof(methodptr*));
2753 M_IADD_IMM(REG_ZERO, 1, d);
2756 emit_label_br(cd, BRANCH_LABEL_4);
2758 emit_label(cd, BRANCH_LABEL_3);
2761 /* class instanceof code */
2763 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2764 if (super == NULL) {
2765 emit_label(cd, BRANCH_LABEL_2);
2767 disp = dseg_add_unique_address(cd, NULL);
2769 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2770 iptr->sx.s23.s3.c.ref,
2774 disp = dseg_add_address(cd, super->vftbl);
2777 emit_label_beq(cd, BRANCH_LABEL_5);
2780 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2781 M_ALD(REG_ITMP2, REG_PV, disp);
2783 CODEGEN_CRITICAL_SECTION_START;
2785 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2786 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2787 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2789 CODEGEN_CRITICAL_SECTION_END;
2791 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2792 M_CMPU(REG_ITMP1, REG_ITMP2);
2795 M_IADD_IMM(REG_ZERO, 1, d);
2798 emit_label(cd, BRANCH_LABEL_5);
2801 if (super == NULL) {
2802 emit_label(cd, BRANCH_LABEL_1);
2803 emit_label(cd, BRANCH_LABEL_4);
2806 emit_store_dst(jd, iptr, d);
2810 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2812 /* check for negative sizes and copy sizes to stack if necessary */
2814 MCODECHECK((iptr->s1.argcount << 1) + 64);
2816 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2817 var = VAR(iptr->sx.s23.s2.args[s1]);
2819 /* copy SAVEDVAR sizes to stack */
2821 /* Already Preallocated? */
2822 if (!(var->flags & PREALLOC)) {
2823 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2824 #if defined(__DARWIN__)
2825 M_IST(s2, REG_SP, LA_SIZE + (s1 + INT_ARG_CNT) * 4);
2827 M_IST(s2, REG_SP, LA_SIZE + (s1 + 3) * 4);
2832 /* a0 = dimension count */
2834 ICONST(REG_A0, iptr->s1.argcount);
2836 /* is patcher function set? */
2838 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2839 disp = dseg_add_unique_address(cd, NULL);
2841 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
2842 iptr->sx.s23.s3.c.ref, disp);
2845 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2847 /* a1 = arraydescriptor */
2849 M_ALD(REG_A1, REG_PV, disp);
2851 /* a2 = pointer to dimensions = stack pointer */
2853 #if defined(__DARWIN__)
2854 M_LDA(REG_A2, REG_SP, LA_SIZE + INT_ARG_CNT * 4);
2856 M_LDA(REG_A2, REG_SP, LA_SIZE + 3 * 4);
2859 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2860 M_ALD(REG_ITMP3, REG_PV, disp);
2864 /* check for exception before result assignment */
2866 emit_exception_check(cd, iptr);
2868 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2869 M_INTMOVE(REG_RESULT, d);
2870 emit_store_dst(jd, iptr, d);
2874 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2879 } /* for instruction */
2881 } /* if (bptr -> flags >= BBREACHED) */
2882 } /* for basic block */
2884 dseg_createlinenumbertable(cd);
2886 /* generate traps */
2888 emit_patcher_traps(jd);
2890 /* everything's ok */
2896 /* codegen_emit_stub_compiler **************************************************
2898 Emits a stub routine which calls the compiler.
2900 *******************************************************************************/
2902 void codegen_emit_stub_compiler(jitdata *jd)
2907 /* get required compiler data */
2912 /* code for the stub */
2914 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P);
2915 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P);
2921 /* codegen_emit_stub_native ****************************************************
2923 Emits a stub routine which calls a native method.
2925 *******************************************************************************/
2927 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2934 s4 i, j; /* count variables */
2939 /* get required compiler data */
2945 /* set some variables */
2948 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2950 /* calculate stackframe size */
2952 cd->stackframesize =
2953 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2954 sizeof(localref_table) / SIZEOF_VOID_P +
2955 4 + /* 4 stackframeinfo arguments (darwin)*/
2956 nmd->paramcount * 2 + /* assume all arguments are doubles */
2959 /* keep stack 16-byte aligned */
2961 cd->stackframesize = (cd->stackframesize + 3) & ~3;
2963 /* create method header */
2965 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2966 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2967 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2968 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2969 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2970 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2971 (void) dseg_addlinenumbertablesize(cd);
2972 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2977 M_AST_INTERN(REG_ZERO, REG_SP, LA_LR_OFFSET);
2978 M_STWU(REG_SP, REG_SP, -(cd->stackframesize * 8));
2980 /* get function address (this must happen before the stackframeinfo) */
2982 funcdisp = dseg_add_functionptr(cd, f);
2984 #if !defined(WITH_STATIC_CLASSPATH)
2986 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
2989 /* emit trace code */
2991 emit_verbosecall_enter(jd);
2993 #if defined(ENABLE_GC_CACAO)
2994 /* Save callee saved integer registers in stackframeinfo (GC may
2995 need to recover them during a collection). */
2997 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
2998 OFFSET(stackframeinfo, intregs);
3000 for (i = 0; i < INT_SAV_CNT; i++)
3001 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3004 /* save integer and float argument registers */
3006 for (i = 0; i < md->paramcount; i++) {
3007 if (!md->params[i].inmemory) {
3008 s1 = md->params[i].regoff;
3010 switch (md->paramtypes[i].type) {
3013 M_IST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
3016 M_LST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
3020 M_DST(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
3026 /* create native stack info */
3028 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A0);
3029 M_MOV(REG_PV, REG_A1);
3030 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3031 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
3032 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3033 M_ALD(REG_ITMP1, REG_PV, disp);
3037 /* restore integer and float argument registers */
3039 for (i = 0; i < md->paramcount; i++) {
3040 if (!md->params[i].inmemory) {
3041 s1 = md->params[i].regoff;
3043 switch (md->paramtypes[i].type) {
3046 M_ILD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
3049 M_LLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
3053 M_DLD(s1, REG_SP, LA_SIZE + 4*4 + i * 8);
3059 /* copy or spill arguments to new locations */
3061 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3062 t = md->paramtypes[i].type;
3064 if (IS_INT_LNG_TYPE(t)) {
3065 if (!md->params[i].inmemory) {
3066 s1 = md->params[i].regoff;
3067 s2 = nmd->params[j].regoff;
3069 if (!nmd->params[j].inmemory) {
3070 if (IS_2_WORD_TYPE(t))
3076 if (IS_2_WORD_TYPE(t))
3077 M_LST(s1, REG_SP, s2);
3079 M_IST(s1, REG_SP, s2);
3083 s1 = md->params[i].regoff + cd->stackframesize * 8;
3084 s2 = nmd->params[j].regoff;
3086 M_ILD(REG_ITMP1, REG_SP, s1);
3087 if (IS_2_WORD_TYPE(t))
3088 M_ILD(REG_ITMP2, REG_SP, s1 + 4);
3090 M_IST(REG_ITMP1, REG_SP, s2);
3091 if (IS_2_WORD_TYPE(t))
3092 M_IST(REG_ITMP2, REG_SP, s2 + 4);
3096 /* We only copy spilled float arguments, as the float
3097 argument registers keep unchanged. */
3099 if (md->params[i].inmemory) {
3100 s1 = md->params[i].regoff + cd->stackframesize * 8;
3101 s2 = nmd->params[j].regoff;
3103 M_DLD(REG_FTMP1, REG_SP, s1);
3105 if (IS_2_WORD_TYPE(t))
3106 M_DST(REG_FTMP1, REG_SP, s2);
3108 M_FST(REG_FTMP1, REG_SP, s2);
3113 /* put class into second argument register */
3115 if (m->flags & ACC_STATIC) {
3116 disp = dseg_add_address(cd, m->class);
3117 M_ALD(REG_A1, REG_PV, disp);
3120 /* put env into first argument register */
3122 disp = dseg_add_address(cd, _Jv_env);
3123 M_ALD(REG_A0, REG_PV, disp);
3125 /* generate the actual native call */
3127 M_ALD(REG_ITMP3, REG_PV, funcdisp);
3131 /* print call trace */
3133 emit_verbosecall_exit(jd);
3135 /* save return value */
3137 switch (md->returntype.type) {
3140 M_IST(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
3143 M_LST(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
3147 M_DST(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
3153 /* remove native stackframe info */
3155 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A0);
3156 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3157 M_ALD(REG_ITMP1, REG_PV, disp);
3160 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3162 /* restore return value */
3164 switch (md->returntype.type) {
3167 M_ILD(REG_RESULT, REG_SP, LA_SIZE + 1 * 8);
3170 M_LLD(REG_RESULT_PACKED, REG_SP, LA_SIZE + 1 * 8);
3174 M_DLD(REG_FRESULT, REG_SP, LA_SIZE + 1 * 8);
3180 #if defined(ENABLE_GC_CACAO)
3181 /* Restore callee saved integer registers from stackframeinfo (GC
3182 might have modified them during a collection). */
3184 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
3185 OFFSET(stackframeinfo, intregs);
3187 for (i = 0; i < INT_SAV_CNT; i++)
3188 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 4);
3191 M_ALD(REG_ITMP2_XPC, REG_SP, cd->stackframesize * 8 + LA_LR_OFFSET);
3192 M_MTLR(REG_ITMP2_XPC);
3193 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* remove stackframe */
3195 /* check for exception */
3197 M_TST(REG_ITMP1_XPTR);
3198 M_BNE(1); /* if no exception then return */
3202 /* handle exception */
3204 M_IADD_IMM(REG_ITMP2_XPC, -4, REG_ITMP2_XPC); /* exception address */
3206 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3207 M_ALD(REG_ITMP3, REG_PV, disp);
3211 /* generate patcher traps */
3213 emit_patcher_traps(jd);
3218 * These are local overrides for various environment variables in Emacs.
3219 * Please do not remove this and leave it at the end of the file, where
3220 * Emacs will automagically detect them.
3221 * ---------------------------------------------------------------------
3224 * indent-tabs-mode: t
3228 * vim:noexpandtab:sw=4:ts=4: