1 /* src/vm/jit/m68k/codegen.c
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
25 $Id: codegen.c 7564 2007-03-23 23:36:17Z twisti $
38 #include "vm/jit/m68k/codegen.h"
39 #include "vm/jit/m68k/emit.h"
41 #include "mm/memory.h"
42 #include "native/jni.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/stringlocal.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/parse.h"
59 #include "vm/jit/patcher.h"
60 #include "vm/jit/reg.h"
61 #include "vm/jit/replace.h"
62 #include "vm/jit/stacktrace.h"
63 #include "vm/jit/md.h"
65 #include "vmcore/loader.h"
66 #include "vmcore/options.h"
67 #include "vmcore/utf8.h"
70 bool codegen_emit(jitdata *jd)
76 s4 len, s1, s2, s3, d, disp;
83 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
84 unresolved_method *um;
85 builtintable_entry *bte;
92 /* get required compiler data */
99 /* prevent compiler warnings */
107 /* save calle saved registers */
108 s4 savedregs_num = 0;
110 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
111 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
112 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
114 cd->stackframesize = rd->memuse + savedregs_num;
116 /* we always add 3 words,
117 * 1 word the lock word, which may be unused and resides @ rd->memuse * 4
118 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 4 + 4
119 * on the other hand we could use 2 words when a builtin returns a doulbe which are
120 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
121 * so we always _need_ at least 2 words, and this keeps the code simple */
122 cd->stackframesize += 3;
125 #if defined(ENABLE_THREADS)
126 /* we need additional space to save argument of monitor_enter */
127 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
128 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
129 cd->stackframesize += 2;
131 cd->stackframesize += 1;
137 /* create method header */
138 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
139 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
140 #if defined(ENABLE_THREADS)
141 if (checksync && (m->flags & ACC_SYNCHRONIZED))
142 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4);/* IsSync */
145 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
146 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
148 /* XXX we use the IntSave a split field for the adr now */
149 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
150 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
152 dseg_addlinenumbertablesize(cd);
154 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
156 /* create exception table */
157 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
158 dseg_add_target(cd, ex->start);
159 dseg_add_target(cd, ex->end);
160 dseg_add_target(cd, ex->handler);
161 (void) dseg_add_unique_address(cd, ex->catchtype.any);
164 #if defined(ENABLE_PROFILING)
169 emit_verbosecall_enter(jd);
171 /* create stack frame */
172 M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
174 /* save used callee saved registers */
175 p = cd->stackframesize;
176 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
177 p--; M_IST(rd->savintregs[i], REG_SP, p*4);
179 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
180 p--; M_AST(rd->savadrregs[i], REG_SP, p*4);
182 #if !defined(ENABLE_SOFTFLOAT)
183 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
184 p-=2; M_FSTORE(rd->savfltregs[i], REG_SP, p*4);
187 assert(FLT_SAV_CNT == 0);
188 assert(rd->savfltreguse == 0);
190 /* take arguments out of stack frame */
192 for (p = 0, l = 0; p < md->paramcount; p++) {
193 t = md->paramtypes[p].type;
194 varindex = jd->local_map[l * 5 + t];
197 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
200 if (varindex == UNUSED)
205 s1 = md->params[p].regoff;
206 assert(md->params[p].inmemory); /* all args are on stack */
209 #if defined(ENABLE_SOFTFLOAT)
215 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
216 if (IS_2_WORD_TYPE(t)) {
217 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
219 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
221 } else { /* stack arg -> spilled */
223 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
224 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
225 if (IS_2_WORD_TYPE(t)) {
226 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4 + 4);
227 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
230 /* Reuse Memory Position on Caller Stack */
231 var->vv.regoff = cd->stackframesize + s1;
235 #if !defined(ENABLE_SOFTFLOAT)
238 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
239 if (IS_2_WORD_TYPE(t)) {
240 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
242 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
244 } else { /* stack-arg -> spilled */
246 if (IS_2_WORD_TYPE(t)) {
247 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
248 M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
250 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
251 M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
254 /* Reuse Memory Position on Caller Stack */
255 var->vv.regoff = cd->stackframesize + s1;
259 #endif /* SOFTFLOAT */
261 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
262 M_ALD(var->vv.regoff, REG_SP, (cd->stackframesize + s1 + 1) * 4);
263 } else { /* stack-arg -> spilled */
265 M_ALD(REG_ATMP1, REG_SP, (cd->stackframesize + s1 + 1) * 4);
266 M_AST(REG_ATMP1, REG_SP, var->vv.regoff * 4);
268 /* Reuse Memory Position on Caller Stack */
269 var->vv.regoff = cd->stackframesize + s1;
275 } /* end for argument out of stack*/
277 #if defined(ENABLE_THREADS)
278 /* call lock_monitor_enter function */
279 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
280 if (m->flags & ACC_STATIC) {
281 M_AMOV_IMM((&m->class->object.header), REG_ATMP1);
283 /* for non-static case the first arg is the object */
284 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize*4 + 4);
287 M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
290 M_AST(REG_ATMP1, REG_SP, rd->memuse * 4);
291 M_AST(REG_ATMP1, REG_SP, 0 * 4);
292 M_JSR_IMM(LOCK_monitor_enter);
298 /* create replacement points */
299 REPLACEMENT_POINTS_INIT(cd, jd);
301 /* foreach basic block */
302 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
304 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
306 if (bptr->flags >= BBREACHED) {
308 /* branch resolving */
309 codegen_resolve_branchrefs(cd, bptr);
311 /* handle replacement points */
312 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
314 #if defined(ENABLE_PROFILING)
317 /* FIXME there are still some constrcuts to copy in here */
319 #if defined(ENABLE_LSRA)
323 /* copy interface registers to their destination */
329 var = VAR(bptr->invars[len]);
330 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
331 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
332 M_ADRMOVE(REG_ATMP1_XPTR, d);
333 emit_store(jd, NULL, var, d);
336 assert((var->flags & INOUT));
340 /* walk through all instructions */
344 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
345 if (iptr->line != currentline) {
346 dseg_addlinenumber(cd, iptr->line);
347 currentline = iptr->line;
350 MCODECHECK(1024); /* 1kB should be enough */
353 case ICMD_NOP: /* ... ==> ... */
354 case ICMD_POP: /* ..., value ==> ... */
355 case ICMD_POP2: /* ..., value, value ==> ... */
358 case ICMD_INLINE_START:
360 REPLACEMENT_POINT_INLINE_START(cd, iptr);
363 case ICMD_INLINE_BODY:
365 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
366 dseg_addlinenumber_inline_start(cd, iptr);
367 dseg_addlinenumber(cd, iptr->line);
370 case ICMD_INLINE_END:
372 dseg_addlinenumber_inline_end(cd, iptr);
373 dseg_addlinenumber(cd, iptr->line);
376 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
378 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
379 assert(VAROP(iptr->s1)->type == TYPE_ADR);
380 emit_nullpointer_check(cd, iptr, s1);
384 /* CONST **************************************************************/
385 case ICMD_ICONST: /* ... ==> ..., constant */
386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
387 M_IMOV_IMM(iptr->sx.val.i, d);
388 emit_store_dst(jd, iptr, d);
391 case ICMD_LCONST: /* ... ==> ..., constant */
393 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
394 LCONST(iptr->sx.val.l, d);
395 emit_store_dst(jd, iptr, d);
398 case ICMD_FCONST: /* ... ==> ..., constant */
400 #if defined(ENABLE_SOFTFLOAT)
401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
402 M_IMOV_IMM(iptr->sx.val.i, d);
403 emit_store_dst(jd, iptr, d);
405 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
406 FCONST(iptr->sx.val.i, d);
407 emit_store_dst(jd, iptr, d);
411 case ICMD_DCONST: /* ... ==> ..., constant */
413 #if defined(ENABLE_SOFTFLOAT)
414 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
415 LCONST(iptr->sx.val.l, d);
416 emit_store_dst(jd, iptr, d);
418 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
419 disp = dseg_add_double(cd, iptr->sx.val.d);
420 M_AMOV_IMM(0, REG_ATMP1);
422 M_DLD(d, REG_ATMP1, disp);
423 emit_store_dst(jd, iptr, d);
429 /* integer operations ************************************************/
430 case ICMD_INEG: /* ..., value ==> ..., - value */
432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
434 M_INTMOVE(s1, REG_ITMP1);
436 M_INTMOVE(REG_ITMP1, d);
437 emit_store_dst(jd, iptr, d);
441 case ICMD_LNEG: /* ..., value ==> ..., - value */
443 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
445 M_SUBFIC(GET_LOW_REG(s1), 0, GET_LOW_REG(d));
446 M_SUBFZE(GET_HIGH_REG(s1), GET_HIGH_REG(d));
447 emit_store_dst(jd, iptr, d);
450 case ICMD_I2L: /* ..., value ==> ..., value */
452 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
454 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
456 M_ISET(GET_HIGH_REG(d));
458 M_ICLR(GET_HIGH_REG(d));
460 emit_store_dst(jd, iptr, d);
463 case ICMD_L2I: /* ..., value ==> ..., value */
465 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
466 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
468 emit_store_dst(jd, iptr, d);
470 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
473 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
475 emit_store_dst(jd, iptr, d);
478 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
480 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
481 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
483 emit_store_dst(jd, iptr, d);
486 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
489 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
491 emit_store_dst(jd, iptr, d);
496 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
499 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
501 M_INTMOVE(s2, REG_ITMP2);
502 M_IADD(s1, REG_ITMP2);
503 M_INTMOVE(REG_ITMP2, d);
504 emit_store_dst(jd, iptr, d);
507 /* s1.localindex = variable, sx.val.i = constant*/
512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
513 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
514 M_INTMOVE(s1, REG_ITMP1);
515 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
516 M_INTMOVE(REG_ITMP1, d);
517 emit_store_dst(jd, iptr, d);
520 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
523 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
524 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
525 M_INTMOVE(s1, REG_ITMP1);
526 M_ISUB(s2, REG_ITMP1);
527 M_INTMOVE(REG_ITMP1, d);
528 emit_store_dst(jd, iptr, d);
531 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
532 /* sx.val.i = constant */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
536 M_INTMOVE(s1, REG_ITMP1);
537 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
538 M_INTMOVE(REG_ITMP1, d);
539 emit_store_dst(jd, iptr, d);
542 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
544 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
546 emit_arithmetic_check(cd, iptr, s2);
547 M_INTMOVE(s1, REG_ITMP1);
548 M_IDIV(s2, REG_ITMP1);
549 M_INTMOVE(REG_ITMP1, d);
550 emit_store_dst(jd, iptr, d);
553 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
556 M_INTMOVE(s1, REG_ITMP1);
560 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
562 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
563 M_ISSR(REG_ITMP2, REG_ITMP1);
564 M_INTMOVE(REG_ITMP1, d);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
572 emit_arithmetic_check(cd, iptr, s2);
574 M_ICMP_IMM(0x80000000, s1);
579 M_TPFL; /* hides the next instruction */
580 M_IREM(s2, s1, REG_ITMP3);
582 M_INTMOVE(REG_ITMP3, d);
584 emit_store_dst(jd, iptr, d);
587 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
591 M_IMOV(s1, REG_ITMP1);
595 M_IAND_IMM(iptr->sx.val.i, d);
597 M_BGE(2 + 2 + 6 + 2);
598 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
600 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
603 emit_store_dst(jd, iptr, d);
607 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
608 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
610 bte = iptr->sx.s23.s3.bte;
613 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
614 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
615 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
616 /* XXX could be optimized */
617 emit_arithmetic_check(cd, iptr, REG_ITMP3);
619 M_LST(s2, REG_SP, 2 * 4);
620 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
621 M_LST(s1, REG_SP, 0 * 4);
625 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
626 M_LNGMOVE(REG_RESULT_PACKED, d);
627 emit_store_dst(jd, iptr, d);
630 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
634 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
635 M_INTMOVE(s2, REG_ITMP2);
636 M_IMUL(s1, REG_ITMP2);
637 M_INTMOVE(REG_ITMP2, d);
638 emit_store_dst(jd, iptr, d);
641 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
642 /* sx.val.i = constant */
643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
645 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
646 M_IMUL(s1, REG_ITMP2);
647 M_INTMOVE(REG_ITMP2, d);
648 emit_store_dst(jd, iptr, d);
651 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
656 M_INTMOVE(s1, REG_ITMP1);
657 M_INTMOVE(s2, REG_ITMP2);
658 M_IAND_IMM(0x1f, REG_ITMP2);
659 M_ISSL(REG_ITMP2, REG_ITMP1);
660 M_INTMOVE(REG_ITMP1, d);
661 emit_store_dst(jd, iptr, d);
664 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
665 /* sx.val.i = constant */
667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
669 if (iptr->sx.val.i & 0x1f) {
670 M_INTMOVE(s1, REG_ITMP1)
671 if ((iptr->sx.val.i & 0x1f) <= 7) {
672 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
674 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
675 M_ISSL(REG_ITMP2, REG_ITMP1);
677 M_INTMOVE(REG_ITMP1, d);
681 emit_store_dst(jd, iptr, d);
684 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
689 M_INTMOVE(s1, REG_ITMP1);
690 M_INTMOVE(s2, REG_ITMP2);
691 M_IAND_IMM(0x1f, REG_ITMP2);
692 M_ISSR(REG_ITMP2, REG_ITMP1);
693 M_INTMOVE(REG_ITMP1, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
698 /* sx.val.i = constant */
700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
702 if (iptr->sx.val.i & 0x1f) {
703 M_INTMOVE(s1, REG_ITMP1)
704 if ((iptr->sx.val.i & 0x1f) <= 7) {
705 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
707 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
708 M_ISSR(REG_ITMP2, REG_ITMP1);
710 M_INTMOVE(REG_ITMP1, d);
714 emit_store_dst(jd, iptr, d);
717 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
722 M_INTMOVE(s1, REG_ITMP1);
723 M_INTMOVE(s2, REG_ITMP2);
724 M_IAND_IMM(0x1f, REG_ITMP2);
725 M_IUSR(REG_ITMP2, REG_ITMP1);
726 M_INTMOVE(REG_ITMP1, d);
727 emit_store_dst(jd, iptr, d);
730 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
731 /* sx.val.i = constant */
732 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
733 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
734 if (iptr->sx.val.i & 0x1f) {
735 M_INTMOVE(s1, REG_ITMP1)
736 if ((iptr->sx.val.i & 0x1f) <= 7) {
737 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
739 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
740 M_IUSR(REG_ITMP2, REG_ITMP1);
742 M_INTMOVE(REG_ITMP1, d);
746 emit_store_dst(jd, iptr, d);
749 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
754 M_INTMOVE(s2, REG_ITMP2);
755 M_IAND(s1, REG_ITMP2);
756 M_INTMOVE(REG_ITMP2, d);
757 emit_store_dst(jd, iptr, d);
760 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
761 /* sx.val.i = constant */
763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
764 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
765 M_INTMOVE(s1, REG_ITMP1);
766 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
767 M_INTMOVE(REG_ITMP1, d);
768 emit_store_dst(jd, iptr, d);
771 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
774 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
775 M_INTMOVE(s2, REG_ITMP2);
776 M_IOR(s1, REG_ITMP2);
777 M_INTMOVE(REG_ITMP2, d);
778 emit_store_dst(jd, iptr, d);
781 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
782 /* sx.val.i = constant */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
785 M_INTMOVE(s1, REG_ITMP1);
786 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
787 M_INTMOVE(REG_ITMP1, d);
788 emit_store_dst(jd, iptr, d);
791 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
793 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
795 M_INTMOVE(s2, REG_ITMP2);
796 M_IXOR(s1, REG_ITMP2);
797 M_INTMOVE(REG_ITMP2, d);
798 emit_store_dst(jd, iptr, d);
801 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
802 /* sx.val.i = constant */
803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
805 M_INTMOVE(s1, REG_ITMP1);
806 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
807 M_INTMOVE(REG_ITMP1, d);
808 emit_store_dst(jd, iptr, d);
811 /* floating point operations ******************************************/
812 #if !defined(ENABLE_SOFTFLOAT)
813 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
815 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
816 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
820 M_BFUN(14); /* result is -1, branch to end */
821 M_BFLT(10); /* result is -1, branch to end */
823 M_BFEQ(4) /* result is 0, branch to end */
825 emit_store_dst(jd, iptr, d);
828 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
830 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
831 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
835 M_BFUN(16); /* result is +1, branch to end */
836 M_BFGT(14); /* result is +1, branch to end */
838 M_BFEQ(8) /* result is 0, branch to end */
840 emit_store_dst(jd, iptr, d);
843 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
844 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
845 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
846 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
847 M_FLTMOVE(s2, REG_FTMP2);
848 M_FMUL(s1, REG_FTMP2);
849 M_FLTMOVE(REG_FTMP2, d);
850 emit_store_dst(jd, iptr, d);
853 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
854 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
855 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
856 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
857 M_DBLMOVE(s2, REG_FTMP2);
858 M_DMUL(s1, REG_FTMP2);
859 M_DBLMOVE(REG_FTMP2, d);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
864 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
865 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
866 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
867 M_FLTMOVE(s1, REG_FTMP1);
868 M_FDIV(s2, REG_FTMP1);
869 M_FLTMOVE(REG_FTMP1, d);
870 emit_store_dst(jd, iptr, d);
873 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
874 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
875 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
876 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
877 M_DBLMOVE(s1, REG_FTMP1);
878 M_DDIV(s2, REG_FTMP1);
879 M_DBLMOVE(REG_FTMP1, d);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
884 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
885 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
886 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
887 M_FLTMOVE(s2, REG_FTMP2);
888 M_FADD(s1, REG_FTMP2);
889 M_FLTMOVE(REG_FTMP2, d);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
894 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
895 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
896 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
897 M_DBLMOVE(s2, REG_FTMP2);
898 M_DADD(s1, REG_FTMP2);
899 M_DBLMOVE(REG_FTMP2, d);
900 emit_store_dst(jd, iptr, d);
903 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
904 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
905 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
906 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
907 M_FLTMOVE(s1, REG_FTMP1);
908 M_FSUB(s2, REG_FTMP1);
909 M_FLTMOVE(REG_FTMP1, d);
910 emit_store_dst(jd, iptr, d);
913 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
914 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
915 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
916 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
917 M_DBLMOVE(s1, REG_FTMP1);
918 M_DSUB(s2, REG_FTMP1);
919 M_DBLMOVE(REG_FTMP1, d);
920 emit_store_dst(jd, iptr, d);
923 case ICMD_F2D: /* ..., value ==> ..., (double) value */
924 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
925 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
927 emit_store_dst(jd, iptr, d);
930 case ICMD_D2F: /* ..., value ==> ..., (float) value */
931 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
932 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
934 emit_store_dst(jd, iptr, d);
937 case ICMD_FNEG: /* ..., value ==> ..., - value */
938 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
939 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
941 emit_store_dst(jd, iptr, d);
944 case ICMD_DNEG: /* ..., value ==> ..., - value */
945 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
946 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
948 emit_store_dst(jd, iptr, d);
953 /* load/store/copy/move operations ************************************/
955 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
956 case ICMD_ALOAD: /* s1 = local variable */
960 case ICMD_ISTORE: /* ..., value ==> ... */
972 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
977 case ICMD_ACONST: /* ... ==> ..., constant */
978 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
980 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
981 constant_classref *cr = iptr->sx.val.c.ref;;
982 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0);
985 M_AMOV_IMM(iptr->sx.val.anyptr, d);
987 emit_store_dst(jd, iptr, d);
989 /* BRANCH *************************************************************/
991 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
993 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
994 M_ADRMOVE(s1, REG_ATMP1_XPTR);
996 #ifdef ENABLE_VERIFIER
997 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
998 unresolved_class *uc = iptr->sx.s23.s2.uc;
1000 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1002 #endif /* ENABLE_VERIFIER */
1003 M_JSR_PCREL(2); /* get current PC */
1006 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1011 case ICMD_GOTO: /* ... ==> ... */
1012 case ICMD_RET: /* ... ==> ... */
1014 emit_br(cd, iptr->dst.block);
1018 case ICMD_JSR: /* ... ==> ... */
1020 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1026 case ICMD_IFNULL: /* ..., value ==> ... */
1027 case ICMD_IFNONNULL:
1028 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1029 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1031 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1039 case ICMD_IFEQ: /* ..., value ==> ... */
1041 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1042 assert (VAROP(iptr->s1)->type == TYPE_INT);
1043 M_ICMP_IMM(iptr->sx.val.i, s1);
1044 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1047 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1048 case ICMD_IF_ICMPNE:
1049 case ICMD_IF_ICMPLT:
1050 case ICMD_IF_ICMPGT:
1051 case ICMD_IF_ICMPLE:
1052 case ICMD_IF_ICMPGE:
1054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1055 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1057 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1060 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1061 case ICMD_IF_ACMPNE:
1063 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1064 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1066 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1070 /* MEMORY *************************************************************/
1071 case ICMD_GETSTATIC:
1072 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1073 uf = iptr->sx.s23.s3.uf;
1074 fieldtype = uf->fieldref->parseddesc.fd->type;
1075 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1077 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1079 fieldtype = fi->type;
1080 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1081 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
1084 disp = (ptrint) &(fi->value);
1086 M_AMOV_IMM(disp, REG_ATMP1);
1087 switch (fieldtype) {
1088 #if defined(ENABLE_SOFTFLOAT)
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1093 M_ILD(d, REG_ATMP1, 0);
1096 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1097 M_ALD(d, REG_ATMP1, 0);
1099 #if defined(ENABLE_SOFTFLOAT)
1103 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1104 M_LLD(d, REG_ATMP1, 0);
1106 #if !defined(ENABLE_SOFTFLOAT)
1108 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1109 M_FLD(d, REG_ATMP1, 0);
1112 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1113 M_DLD(d, REG_ATMP1, 0);
1117 emit_store_dst(jd, iptr, d);
1120 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1122 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1123 uf = iptr->sx.s23.s3.uf;
1124 fieldtype = uf->fieldref->parseddesc.fd->type;
1126 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1128 fi = iptr->sx.s23.s3.fmiref->p.field;
1129 fieldtype = fi->type;
1130 disp = &(fi->value);
1132 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1133 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
1136 M_AMOV_IMM(disp, REG_ATMP1);
1137 switch (fieldtype) {
1138 #if defined(ENABLE_SOFTFLOAT)
1142 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1143 M_IST(s1, REG_ATMP1, 0);
1145 #if defined(ENABLE_SOFTFLOAT)
1149 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1150 M_LST(s1, REG_ATMP1, 0);
1153 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1154 M_AST(s1, REG_ATMP1, 0);
1156 #if !defined(ENABLE_SOFTFLOAT)
1158 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1159 M_FST(s1, REG_ATMP1, 0);
1162 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1163 M_DST(s1, REG_ATMP1, 0);
1170 case ICMD_GETFIELD: /* ... ==> ..., value */
1172 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1174 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1175 uf = iptr->sx.s23.s3.uf;
1176 fieldtype = uf->fieldref->parseddesc.fd->type;
1179 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1182 fi = iptr->sx.s23.s3.fmiref->p.field;
1183 fieldtype = fi->type;
1187 /* implicit null-pointer check */
1188 switch (fieldtype) {
1189 #if defined(ENABLE_SOFTFLOAT)
1193 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1196 #if defined(ENABLE_SOFTFLOAT)
1200 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1204 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1207 #if !defined(ENABLE_SOFTFLOAT)
1209 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1213 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1218 emit_store_dst(jd, iptr, d);
1221 case ICMD_PUTFIELD: /* ..., value ==> ... */
1223 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1225 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1226 uf = iptr->sx.s23.s3.uf;
1227 fieldtype = uf->fieldref->parseddesc.fd->type;
1231 fi = iptr->sx.s23.s3.fmiref->p.field;
1232 fieldtype = fi->type;
1236 if (IS_INT_LNG_TYPE(fieldtype)) {
1237 if (IS_2_WORD_TYPE(fieldtype)) {
1238 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1240 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1243 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1246 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1247 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1249 /* implicit null-pointer check */
1250 switch (fieldtype) {
1251 #if defined(ENABLE_SOFTFLOAT)
1255 M_IST(s2, s1, disp);
1258 #if defined(ENABLE_SOFTFLOAT)
1262 M_LST(s2, s1, disp);
1265 M_AST(s2, s1, disp);
1267 #if !defined(ENABLE_SOFTFLOAT)
1269 M_FST(s2, s1, disp);
1272 M_DST(s2, s1, disp);
1278 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1280 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1281 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1282 /* implicit null-pointer check */
1283 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1284 emit_store_dst(jd, iptr, d);
1287 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1289 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1290 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1291 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1292 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1293 M_INTMOVE(s2, REG_ITMP2);
1294 M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1295 M_ADRMOVE(s1, REG_ATMP1);
1296 M_AADDINT(REG_ITMP2, REG_ATMP1);
1297 /* implicit null-pointer check */
1298 M_LBZX(REG_ATMP1, d);
1300 emit_store_dst(jd, iptr, d);
1303 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1305 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1306 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1307 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1308 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1309 M_INTMOVE(s2, REG_ITMP2);
1310 M_ISSL_IMM(1, REG_ITMP2);
1311 M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2);
1312 M_ADRMOVE(s1, REG_ATMP1);
1313 M_AADDINT(REG_ITMP2, REG_ATMP1);
1314 /* implicit null-pointer check */
1315 M_LHZX(REG_ATMP1, d);
1317 emit_store_dst(jd, iptr, d);
1320 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1322 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1323 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1324 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1325 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1326 M_INTMOVE(s2, REG_ITMP2);
1327 M_ISSL_IMM(1, REG_ITMP2);
1328 M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1329 M_ADRMOVE(s1, REG_ATMP1);
1330 M_AADDINT(REG_ITMP2, REG_ATMP1);
1332 /* implicit null-pointer check */
1333 M_LHZX(REG_ATMP1, d);
1335 emit_store_dst(jd, iptr, d);
1338 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1340 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1342 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1343 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1344 M_INTMOVE(s2, REG_ITMP2);
1345 M_ISSL_IMM(2, REG_ITMP2);
1346 M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1347 M_ADRMOVE(s1, REG_ATMP1);
1348 M_AADDINT(REG_ITMP2, REG_ATMP1);
1349 /* implicit null-pointer check */
1350 M_LWZX(REG_ATMP1, d);
1351 emit_store_dst(jd, iptr, d);
1354 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1355 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1356 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1357 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1358 /* implicit null-pointer check */
1359 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1360 M_INTMOVE(s2, REG_ITMP1);
1361 M_ISSL_IMM(3, REG_ITMP1);
1362 M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1);
1363 M_ADRMOVE(s1, REG_ATMP1);
1364 M_AADDINT(REG_ITMP1, REG_ATMP1);
1365 /* implicit null-pointer check */
1366 M_LLD(d, REG_ATMP1, 0);
1367 emit_store_dst(jd, iptr, d);
1370 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1371 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1372 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1373 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1374 M_INTMOVE(s2, REG_ITMP2);
1375 M_ISSL_IMM(2, REG_ITMP2);
1376 M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2);
1377 M_ADRMOVE(s1, REG_ATMP1);
1378 M_AADDINT(REG_ITMP2, REG_ATMP1);
1379 /* implicit null-pointer check */
1380 #if !defined(ENABLE_SOFTFLOAT)
1381 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1382 M_FLD(d, REG_ATMP1, 0);
1384 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1385 M_LWZX(REG_ATMP1, d);
1387 emit_store_dst(jd, iptr, d);
1390 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1391 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1392 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1393 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1394 M_INTMOVE(s2, REG_ITMP2);
1395 M_ISSL_IMM(3, REG_ITMP2);
1396 M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2);
1397 M_ADRMOVE(s1, REG_ATMP1);
1398 M_AADDINT(REG_ITMP2, REG_ATMP1);
1399 /* implicit null-pointer check */
1400 #if !defined(ENABLE_SOFTFLOAT)
1401 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1402 M_DLD(d, REG_ATMP1, 0);
1404 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1405 M_LLD(d, REG_ATMP1, 0);
1407 emit_store_dst(jd, iptr, d);
1410 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1411 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1412 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1413 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1414 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1415 M_INTMOVE(s2, REG_ITMP2);
1416 M_ISSL_IMM(2, REG_ITMP2);
1417 M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP2);
1418 M_ADRMOVE(s1, REG_ATMP1);
1419 M_AADDINT(REG_ITMP2, REG_ATMP1);
1421 /* implicit null-pointer check */
1422 M_LAX(REG_ATMP1, d);
1423 emit_store_dst(jd, iptr, d);
1427 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1428 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1429 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1431 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1432 M_INTMOVE(s2, REG_ITMP2);
1433 M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1434 M_ADRMOVE(s1, REG_ATMP1);
1435 M_AADDINT(REG_ITMP2, REG_ATMP1);
1436 /* implicit null-pointer check */
1437 M_STBX(REG_ATMP1, s3);
1440 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1442 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1443 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1444 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1445 M_INTMOVE(s2, REG_ITMP2);
1446 M_ISSL_IMM(1, REG_ITMP2);
1447 M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2);
1448 M_ADRMOVE(s1, REG_ATMP1);
1449 M_AADDINT(REG_ITMP2, REG_ATMP1);
1450 /* implicit null-pointer check */
1451 M_STHX(REG_ATMP1, s3);
1454 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1455 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1456 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1457 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1458 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1459 M_INTMOVE(s2, REG_ITMP2);
1460 M_ISSL_IMM(1, REG_ITMP2);
1461 M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1462 M_ADRMOVE(s1, REG_ATMP1);
1463 M_AADDINT(REG_ITMP2, REG_ATMP1);
1464 /* implicit null-pointer check */
1465 M_STHX(REG_ATMP1, s3);
1468 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1469 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1470 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1471 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1472 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1473 M_INTMOVE(s2, REG_ITMP2);
1474 M_ISSL_IMM(2, REG_ITMP2);
1475 M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1476 M_ADRMOVE(s1, REG_ATMP1);
1477 M_AADDINT(REG_ITMP2, REG_ATMP1);
1478 /* implicit null-pointer check */
1479 M_STWX(REG_ATMP1, s3);
1482 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1483 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1485 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1487 M_INTMOVE(s2, REG_ITMP1);
1488 M_ISSL_IMM(3, REG_ITMP1);
1489 M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1);
1490 M_ADRMOVE(s1, REG_ATMP1);
1491 M_AADDINT(REG_ITMP1, REG_ATMP1);
1492 /* implicit null-pointer check */
1493 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1494 M_LST(s3, REG_ATMP1, 0);
1497 case ICMD_FASTORE: /* ..., 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 M_INTMOVE(s2, REG_ITMP2);
1502 M_ISSL_IMM(2, REG_ITMP2);
1503 M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2);
1504 M_ADRMOVE(s1, REG_ATMP1);
1505 M_AADDINT(REG_ITMP2, REG_ATMP1);
1506 /* implicit null-pointer check */
1507 #if !defined(ENABLE_SOFTFLOAT)
1508 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1509 M_FST(s3, REG_ATMP1, 0);
1511 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1512 M_STWX(REG_ATMP1, s3);
1516 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1520 M_INTMOVE(s2, REG_ITMP2);
1521 M_ISSL_IMM(3, REG_ITMP2);
1522 M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2);
1523 M_ADRMOVE(s1, REG_ATMP1);
1524 M_AADDINT(REG_ITMP2, REG_ATMP1);
1525 /* implicit null-pointer check */
1526 #if !defined(ENABLE_SOFTFLOAT)
1527 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1528 M_DST(s3, REG_ATMP1, 0);
1530 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1531 /* implicit null-pointer check */
1532 M_LST(s3, REG_ATMP1, 0);
1536 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1538 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1539 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1540 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1541 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1543 /* XXX what if array is NULL */
1544 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1546 M_AST(s1, REG_SP, 0*4);
1547 M_AST(s3, REG_SP, 1*4);
1548 M_JSR_IMM(BUILTIN_canstore);
1549 emit_exception_check(cd, iptr);
1551 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1552 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1553 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1554 M_INTMOVE(s2, REG_ITMP1);
1555 M_ISSL_IMM(2, REG_ITMP1);
1556 M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP1);
1557 M_ADRMOVE(s1, REG_ATMP1);
1558 M_AADDINT(REG_ITMP1, REG_ATMP1);
1559 /* implicit null-pointer check */
1560 M_STAX(REG_ATMP1, s3);
1565 /* METHOD INVOCATION *********************************************************/
1566 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1567 bte = iptr->sx.s23.s3.bte;
1571 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1572 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1573 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1574 case ICMD_INVOKEINTERFACE:
1575 REPLACEMENT_POINT_INVOKE(cd, iptr);
1577 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1579 um = iptr->sx.s23.s3.um;
1580 md = um->methodref->parseddesc.md;
1583 lm = iptr->sx.s23.s3.fmiref->p.method;
1585 md = lm->parseddesc;
1588 s3 = md->paramcount;
1590 MCODECHECK((s3 << 1) + 64);
1592 /* copy arguments to stack */
1593 for (s3 = s3 - 1; s3 >= 0; s3--) {
1594 var = VAR(iptr->sx.s23.s2.args[s3]);
1595 /* already preallocated */
1596 if (var->flags & PREALLOC) continue;
1598 if (!md->params[s3].inmemory) assert(0);
1600 switch (var->type) {
1601 #if defined(ENABLE_SOFTFLOAT)
1605 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1606 M_LST(d, REG_SP, md->params[s3].regoff*4);
1608 #if defined(ENABLE_SOFTFLOAT)
1612 d = emit_load(jd, iptr, var, REG_ITMP1);
1613 M_IST(d, REG_SP, md->params[s3].regoff*4);
1616 d = emit_load(jd, iptr, var, REG_ATMP1);
1617 M_AST(d, REG_SP, md->params[s3].regoff*4);
1619 #if !defined(ENABLE_SOFTFLOAT)
1621 d = emit_load(jd, iptr, var, REG_FTMP1);
1622 M_FST(d, REG_SP, md->params[s3].regoff*4);
1625 d = emit_load(jd, iptr, var, REG_FTMP1);
1626 M_DST(d, REG_SP, md->params[s3].regoff*4);
1634 /* arguments in place now */
1637 disp = (ptrint) bte->fp;
1638 d = md->returntype.type;
1641 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1642 emit_exception_check(cd, iptr);
1645 case ICMD_INVOKESPECIAL:
1646 /* adress register for sure */
1647 M_ALD(REG_ATMP1, REG_SP, 0);
1648 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1650 case ICMD_INVOKESTATIC:
1652 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1654 M_AMOV_IMM(disp, REG_ATMP1);
1656 disp = lm->stubroutine;
1657 M_AMOV_IMM(disp, REG_ATMP1);
1660 /* generate the actual call */
1662 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1666 case ICMD_INVOKEVIRTUAL:
1668 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1671 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1673 /* load object pointer (==argument 0) */
1674 M_ALD(REG_ATMP1, REG_SP, 0);
1675 /* implicit null-pointer check */
1676 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1677 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1678 /* generate the actual call */
1681 case ICMD_INVOKEINTERFACE:
1683 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1688 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1689 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1691 /* load object pointer (==argument 0) */
1692 M_ALD(REG_ATMP1, REG_SP, 0);
1694 /* implicit null-pointer check */
1695 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_objectheader, vftbl));
1696 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1697 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1699 /* generate the actual call */
1701 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1705 } /* switch (iptr->opc) */
1707 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1709 /* store return value */
1710 d = md->returntype.type;
1713 case TYPE_VOID: break;
1714 #if defined(ENABLE_SOFTFLOAT)
1718 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1719 M_INTMOVE(REG_RESULT, s1);
1721 #if defined(ENABLE_SOFTFLOAT)
1725 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1726 M_LNGMOVE(REG_RESULT_PACKED, s1);
1729 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1730 /* all stuff is returned in %d0 */
1731 M_INT2ADRMOVE(REG_RESULT, s1);
1733 #if !defined(ENABLE_SOFTFLOAT)
1735 * for BUILTINS float values are returned in %d0,%d1
1736 * within cacao we use %fp0 for that.
1739 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1740 if (iptr->opc == ICMD_BUILTIN) {
1741 M_INT2FLTMOVE(REG_FRESULT, s1);
1743 M_FLTMOVE(REG_FRESULT, s1);
1747 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1748 if (iptr->opc == ICMD_BUILTIN) {
1749 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1750 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1752 M_DBLMOVE(REG_FRESULT, s1);
1759 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1760 break; /* ICMD_INVOKE* */
1762 #if defined(ENABLE_SOFTFLOAT)
1765 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1767 REPLACEMENT_POINT_RETURN(cd, iptr);
1768 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1769 M_INTMOVE(s1, REG_RESULT);
1770 goto nowperformreturn;
1772 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1774 REPLACEMENT_POINT_RETURN(cd, iptr);
1775 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1776 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1777 M_ADR2INTMOVE(s1, REG_RESULT);
1779 #ifdef ENABLE_VERIFIER
1780 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1781 unresolved_class *uc = iptr->sx.s23.s2.uc;
1783 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1785 #endif /* ENABLE_VERIFIER */
1786 goto nowperformreturn;
1788 #if defined(ENABLE_SOFTFLOAT)
1791 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1792 REPLACEMENT_POINT_RETURN(cd, iptr);
1793 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1794 M_LNGMOVE(s1, REG_RESULT_PACKED);
1795 goto nowperformreturn;
1797 #if !defined(ENABLE_SOFTFLOAT)
1798 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1799 REPLACEMENT_POINT_RETURN(cd, iptr);
1800 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1801 M_FLTMOVE(s1, REG_FRESULT);
1802 goto nowperformreturn;
1805 REPLACEMENT_POINT_RETURN(cd, iptr);
1806 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1807 M_DBLMOVE(s1, REG_FRESULT);
1808 goto nowperformreturn;
1812 case ICMD_RETURN: /* ... ==> ... */
1814 REPLACEMENT_POINT_RETURN(cd, iptr);
1820 p = cd->stackframesize;
1822 /* call trace function */
1823 #if !defined(NDEBUG)
1824 emit_verbosecall_exit(jd);
1827 #if defined(ENABLE_THREADS)
1828 /* call lock_monitor_exit */
1829 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1830 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 4);
1832 /* we need to save the proper return value */
1833 /* we do not care for the long -> doubel convert space here */
1834 switch (iptr->opc) {
1835 #if defined(ENABLE_SOFTFLOAT)
1839 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1841 #if defined(ENABLE_SOFTFLOAT)
1846 M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
1848 #if !defined(ENABLE_SOFTFLOAT)
1850 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1853 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1858 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1859 M_JSR_IMM(LOCK_monitor_exit);
1861 /* and now restore the proper return value */
1862 switch (iptr->opc) {
1864 #if defined(ENABLE_SOFTFLOAT)
1868 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1870 #if defined(ENABLE_SOFTFLOAT)
1875 M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
1877 #if !defined(ENABLE_SOFTFLOAT)
1879 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1882 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
1890 /* restore return address */
1892 if (!jd->isleafmethod) {
1893 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1894 may have a displacement overflow. */
1896 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1900 /* restore saved registers */
1902 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1903 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
1905 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1906 p--; M_ALD(rd->savadrregs[i], REG_SP, p*4);
1908 #if !defined(ENABLE_SOFTFLOAT)
1909 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1910 p -= 2; M_FLOAD(rd->savfltregs[i], REG_SP, p * 4);
1913 /* deallocate stack */
1914 M_AADD_IMM(cd->stackframesize*4, REG_SP);
1920 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1921 /* val.a: (classinfo*) superclass */
1923 /* superclass is an interface:
1925 * return (sub != NULL) &&
1926 * (sub->vftbl->interfacetablelength > super->index) &&
1927 * (sub->vftbl->interfacetable[-super->index] != NULL);
1929 * superclass is a class:
1931 * return ((sub != NULL) && (0
1932 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1933 * super->vftbl->diffvall));
1940 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1945 super = iptr->sx.s23.s3.c.cls;
1946 superindex = super->index;
1949 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
1950 CODEGEN_CRITICAL_SECTION_NEW;
1952 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1953 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1955 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
1956 assert(VAROP(iptr->dst)->type == TYPE_INT);
1960 /* if class is not resolved, check which code to call */
1962 if (super == NULL) {
1964 emit_label_beq(cd, BRANCH_LABEL_1);
1966 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1968 M_IMOV_IMM32(0, REG_ITMP3);
1969 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
1970 emit_label_beq(cd, BRANCH_LABEL_2);
1973 /* interface instanceof code */
1975 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1976 if (super == NULL) {
1977 codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
1980 emit_label_beq(cd, BRANCH_LABEL_3);
1983 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
1984 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
1985 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
1988 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
1994 emit_label_br(cd, BRANCH_LABEL_4);
1996 emit_label(cd, BRANCH_LABEL_3);
1999 /* class instanceof code */
2001 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2002 if (super == NULL) {
2003 emit_label(cd, BRANCH_LABEL_2);
2005 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2006 M_AMOV_IMM(0, REG_ATMP2);
2008 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2010 emit_label_beq(cd, BRANCH_LABEL_5);
2013 M_ALD(REG_ATMP1, s1, OFFSET(java_objectheader, vftbl));
2015 CODEGEN_CRITICAL_SECTION_START;
2017 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2018 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2019 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2021 CODEGEN_CRITICAL_SECTION_END;
2023 M_ISUB(REG_ITMP3, REG_ITMP1);
2024 M_ICMP(REG_ITMP2, REG_ITMP1);
2027 M_TPFW; /* overlaps next instruction */
2031 emit_label(cd, BRANCH_LABEL_5);
2034 if (super == NULL) {
2035 emit_label(cd, BRANCH_LABEL_1);
2036 emit_label(cd, BRANCH_LABEL_4);
2039 emit_store_dst(jd, iptr, d);
2043 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2044 /* val.a: (classinfo*) superclass */
2046 /* superclass is an interface:
2048 * OK if ((sub == NULL) ||
2049 * (sub->vftbl->interfacetablelength > super->index) &&
2050 * (sub->vftbl->interfacetable[-super->index] != NULL));
2052 * superclass is a class:
2054 * OK if ((sub == NULL) || (0
2055 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2056 * super->vftbl->diffvall));
2059 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2060 /* object type cast-check */
2065 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2070 super = iptr->sx.s23.s3.c.cls;
2071 superindex = super->index;
2074 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2075 CODEGEN_CRITICAL_SECTION_NEW;
2077 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2078 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2080 /* if class is not resolved, check which code to call */
2082 if (super == NULL) {
2084 emit_label_beq(cd, BRANCH_LABEL_1);
2086 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2088 M_IMOV_IMM32(0, REG_ITMP2);
2089 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2090 emit_label_beq(cd, BRANCH_LABEL_2);
2093 /* interface checkcast code */
2095 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2096 if (super == NULL) {
2097 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2100 emit_label_beq(cd, BRANCH_LABEL_3);
2103 M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
2104 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2106 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2108 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2110 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2112 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2115 emit_label_br(cd, BRANCH_LABEL_4);
2117 emit_label(cd, BRANCH_LABEL_3);
2120 /* class checkcast code */
2122 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2123 if (super == NULL) {
2124 emit_label(cd, BRANCH_LABEL_2);
2126 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2127 M_AMOV_IMM(0, REG_ATMP3);
2129 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2131 emit_label_beq(cd, BRANCH_LABEL_5);
2134 M_ALD(REG_ATMP2, s1, OFFSET(java_objectheader, vftbl));
2136 CODEGEN_CRITICAL_SECTION_START;
2138 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2139 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2140 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2142 CODEGEN_CRITICAL_SECTION_END;
2144 M_ISUB(REG_ITMP1, REG_ITMP3);
2145 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2147 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2150 emit_label(cd, BRANCH_LABEL_5);
2153 if (super == NULL) {
2154 emit_label(cd, BRANCH_LABEL_1);
2155 emit_label(cd, BRANCH_LABEL_4);
2158 d = codegen_reg_of_dst(jd, iptr, s1);
2160 /* array type cast-check */
2162 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2164 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2165 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2166 M_AMOV_IMM(0, REG_ATMP1);
2168 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2173 M_JSR_IMM(BUILTIN_arraycheckcast);
2174 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2176 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 d = codegen_reg_of_dst(jd, iptr, s1);
2181 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2183 emit_store_dst(jd, iptr, d);
2186 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2189 branch_target_t *table;
2191 table = iptr->dst.table;
2193 l = iptr->sx.s23.s2.tablelow;
2194 i = iptr->sx.s23.s3.tablehigh;
2196 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2197 M_INTMOVE(s1, REG_ITMP1);
2198 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2203 M_ICMP_IMM(i - 1, REG_ITMP1);
2204 emit_bugt(cd, table[0].block);
2206 /* build jump table top down and use address of lowest entry */
2210 dseg_add_target(cd, table->block);
2214 /* length of dataseg after last dseg_add_target is used by load */
2215 M_AMOV_IMM(0, REG_ATMP2);
2218 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2219 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2220 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2221 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2228 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2231 lookup_target_t *lookup;
2233 lookup = iptr->dst.lookup;
2235 i = iptr->sx.s23.s2.lookupcount;
2237 MCODECHECK((i<<2)+8);
2238 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2241 M_ICMP_IMM(lookup->value, s1);
2242 emit_beq(cd, lookup->target.block);
2246 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2251 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2253 /* check for negative sizes and copy sizes to stack if necessary */
2254 MCODECHECK((iptr->s1.argcount << 1) + 64);
2256 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2257 var = VAR(iptr->sx.s23.s2.args[s1]);
2259 /* Already Preallocated? */
2260 if (!(var->flags & PREALLOC)) {
2261 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2262 M_IST(s2, REG_SP, (s1 + 3) * 4);
2266 /* a0 = dimension count */
2267 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2268 M_IST(REG_ITMP1, REG_SP, 0*4);
2270 /* a1 = arraydescriptor */
2271 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2272 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2273 M_AMOV_IMM(0, REG_ATMP1);
2275 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2277 M_AST(REG_ATMP1, REG_SP, 1*4);
2279 /* a2 = pointer to dimensions = stack pointer */
2280 M_AMOV(REG_SP, REG_ATMP1);
2281 M_AADD_IMM(3*4, REG_ATMP1);
2282 M_AST(REG_ATMP1, REG_SP, 2*4);
2284 M_JSR_IMM(BUILTIN_multianewarray);
2286 /* check for exception before result assignment */
2287 emit_exception_check(cd, iptr);
2289 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2290 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2291 M_INT2ADRMOVE(REG_RESULT, d);
2292 emit_store_dst(jd, iptr, d);
2298 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2299 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2303 } /* for each instruction */
2304 } /* if (btpre->flags >= BBREACHED) */
2305 } /* for each basic block */
2307 dseg_createlinenumbertable(cd);
2309 /* generate stubs */
2310 emit_patcher_stubs(jd);
2311 REPLACEMENT_EMIT_STUBS(jd);
2317 /* codegen_emit_stub_compiler **************************************************
2319 Emits a stub routine which calls the compiler.
2321 *******************************************************************************/
2323 void codegen_emit_stub_compiler(jitdata *jd)
2328 /* get required compiler data */
2333 /* code for the stub */
2335 M_AMOV_IMM(m, REG_ATMP1);
2336 M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2341 /* codegen_emit_stub_native ****************************************************
2343 Emits a stub routine which calls a native method.
2345 *******************************************************************************/
2347 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2354 s4 nativeparams, i, j, t, s1, s2;
2356 /* get required compiler data */
2364 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2366 /* calc stackframe size */
2367 cd->stackframesize = sizeof(stackframeinfo) / SIZEOF_VOID_P +
2368 sizeof(localref_table) / SIZEOF_VOID_P +
2370 1 + /* functionptr */
2371 4; /* args for codegen_start_native_call */
2373 /* create method header */
2374 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2375 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
2376 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2377 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2378 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2379 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2380 (void) dseg_addlinenumbertablesize(cd);
2381 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2383 /* print call trace */
2384 #if !defined(NDEBUG)
2385 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2386 emit_verbosecall_enter(jd);
2391 M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2393 /* get function address (this must happen before the stackframeinfo) */
2394 #if !defined(WITH_STATIC_CLASSPATH)
2396 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2399 M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2401 M_AST(REG_ATMP2, REG_SP, 4 * 4);
2403 /* put arguments for codegen_start_native_call onto stack */
2404 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2406 M_AMOV(REG_SP, REG_ATMP1);
2407 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2409 M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
2410 M_AST(REG_ATMP3, REG_SP, 3 * 4); /* ra */
2412 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* datasp */
2414 M_AADD_IMM(1 * 4 , REG_ATMP1);
2415 M_AST(REG_ATMP1, REG_SP, 2 * 4); /* sp */
2417 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2418 dseg_adddata(cd); /* this patches it */
2420 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2422 M_JSR_IMM(codegen_start_native_call);
2424 /* load function pointer */
2425 M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2427 /* copy arguments into stackframe */
2428 for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j) {
2429 t = md->paramtypes[i].type;
2430 /* all arguments via stack */
2431 assert(md->params[i].inmemory);
2433 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
2434 s2 = nmd->params[j].regoff * 4;
2436 /* simply copy argument stack */
2437 M_ILD(REG_ITMP1, REG_SP, s1);
2438 M_IST(REG_ITMP1, REG_SP, s2);
2439 if (IS_2_WORD_TYPE(t)) {
2440 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2441 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2445 /* for static function class as second arg */
2446 if (m->flags & ACC_STATIC) {
2447 M_AMOV_IMM(m->class, REG_ATMP1);
2448 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2450 /* env ist first argument */
2451 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2452 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2454 /* call the native function */
2457 /* save return value */
2458 switch (md->returntype.type) {
2459 case TYPE_VOID: break;
2461 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2464 M_IST(REG_D1, REG_SP, 2 * 4);
2470 M_IST(REG_D0, REG_SP, 1 * 4);
2476 /* print call trace */
2477 #if ! defined(NDEBUG)
2478 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2479 emit_verbosecall_exit(jd);
2482 /* remove native stackframe info */
2483 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2485 M_AMOV(REG_SP, REG_ATMP3);
2486 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2487 M_AST(REG_ATMP3, REG_SP, 0 * 4); /* datasp */
2488 M_JSR_IMM(codegen_finish_native_call);
2490 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2491 /* restore return value */
2492 switch (md->returntype.type) {
2493 case TYPE_VOID: break;
2497 M_ILD(REG_D1, REG_SP, 2 * 4);
2502 M_ILD(REG_D0, REG_SP, 1 * 4);
2507 #if !defined(ENABLE_SOFTFLOAT)
2508 /* additionally load values into floating points registers
2509 * as cacao jit code expects them there */
2510 switch (md->returntype.type) {
2512 M_FLD(REG_D0, REG_SP, 1 * 4);
2515 M_DLD(REG_D0, REG_SP, 1 * 4);
2519 /* restore saved registers */
2521 M_AADD_IMM(cd->stackframesize*4, REG_SP);
2522 /* check for exception */
2527 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2529 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2530 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2531 M_JMP_IMM(asm_handle_nat_exception);
2533 /* should never be reached from within jit code*/
2536 /* generate patcher stub call code */
2537 emit_patcher_stubs(jd);
2542 * These are local overrides for various environment variables in Emacs.
2543 * Please do not remove this and leave it at the end of the file, where
2544 * Emacs will automagically detect them.
2545 * ---------------------------------------------------------------------
2548 * indent-tabs-mode: t
2552 * vim:noexpandtab:sw=4:ts=4: