1 /* src/vm/jit/m68k/codegen.c
3 Copyright (C) 1996-2005, 2006, 2007, 2008
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "vm/jit/m68k/codegen.h"
35 #include "vm/jit/m68k/emit.h"
37 #include "mm/memory.h"
38 #include "native/jni.h"
39 #include "native/localref.h"
40 #include "native/native.h"
42 #include "threads/lock-common.h"
44 #include "vm/builtin.h"
45 #include "vm/exceptions.hpp"
46 #include "vm/global.h"
49 #include "vm/jit/asmpart.h"
50 #include "vm/jit/codegen-common.h"
51 #include "vm/jit/patcher-common.h"
52 #include "vm/jit/dseg.h"
53 #include "vm/jit/linenumbertable.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/jit.h"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/parse.h"
58 #include "vm/jit/reg.h"
59 #include "vm/jit/replace.h"
60 #include "vm/jit/stacktrace.hpp"
61 #include "vm/jit/trap.h"
63 #include "vmcore/loader.h"
64 #include "vmcore/options.h"
65 #include "vmcore/utf8.h"
68 bool codegen_emit(jitdata *jd)
74 s4 len, s1, s2, s3, d, disp;
79 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
80 unresolved_method *um;
81 builtintable_entry *bte;
88 /* get required compiler data */
95 /* prevent compiler warnings */
103 /* save calle saved registers */
104 s4 savedregs_num = 0;
106 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
107 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
108 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
110 cd->stackframesize = rd->memuse + savedregs_num;
112 /* we always add 2 stack slots.
113 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
114 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
115 * on the other hand we could use 2 words when a builtin returns a doulbe which are
116 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
117 * so we always _need_ at least 2 slots, and this keeps the code simple */
118 cd->stackframesize += 2;
120 cd->stackframesize *= 8; /* we use 8 byte stack slots */
123 #if defined(ENABLE_THREADS)
124 /* we need additional space to save argument of monitor_enter */
125 if (checksync && code_is_synchronized(code)) {
126 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
127 cd->stackframesize += 2;
129 cd->stackframesize += 1;
135 /* create method header */
136 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
137 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
139 code->synchronizedoffset = rd->memuse * 8;
141 /* REMOVEME: We still need it for exception handling in assembler. */
143 if (code_is_leafmethod(code))
144 (void) dseg_add_unique_s4(cd, 1);
146 (void) dseg_add_unique_s4(cd, 0);
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 #if defined(ENABLE_PROFILING)
157 emit_verbosecall_enter(jd);
159 /* create stack frame */
160 M_AADD_IMM(-(cd->stackframesize), REG_SP);
162 /* save used callee saved registers */
163 p = cd->stackframesize;
164 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
165 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
167 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
168 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
170 #if !defined(ENABLE_SOFTFLOAT)
171 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
172 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
175 assert(FLT_SAV_CNT == 0);
176 assert(rd->savfltreguse == 0);
178 /* take arguments out of stack frame */
180 for (p = 0, l = 0; p < md->paramcount; p++) {
181 t = md->paramtypes[p].type;
182 varindex = jd->local_map[l * 5 + t];
185 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
188 if (varindex == UNUSED)
193 s1 = md->params[p].regoff;
194 assert(md->params[p].inmemory); /* all args are on stack */
197 #if defined(ENABLE_SOFTFLOAT)
203 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
204 if (IS_2_WORD_TYPE(t)) {
205 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
207 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
209 } else { /* stack arg -> spilled */
210 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
211 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
212 if (IS_2_WORD_TYPE(t)) {
213 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
214 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
218 #if !defined(ENABLE_SOFTFLOAT)
221 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
222 if (IS_2_WORD_TYPE(t)) {
223 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
225 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
227 } else { /* stack-arg -> spilled */
228 if (IS_2_WORD_TYPE(t)) {
229 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
230 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
232 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
233 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
237 #endif /* SOFTFLOAT */
239 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
240 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
241 } else { /* stack-arg -> spilled */
242 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
243 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
248 } /* end for argument out of stack*/
250 #if defined(ENABLE_THREADS)
251 /* call lock_monitor_enter function */
252 if (checksync && code_is_synchronized(code)) {
253 if (m->flags & ACC_STATIC) {
254 M_AMOV_IMM((&m->clazz->object.header), REG_ATMP1);
256 /* for non-static case the first arg is the object */
257 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
260 M_TRAP(TRAP_NullPointerException);
263 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
264 M_AST(REG_ATMP1, REG_SP, 0 * 4);
265 M_JSR_IMM(LOCK_monitor_enter);
271 /* create replacement points */
272 REPLACEMENT_POINTS_INIT(cd, jd);
274 /* foreach basic block */
275 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
277 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
279 if (bptr->flags >= BBREACHED) {
281 /* branch resolving */
282 codegen_resolve_branchrefs(cd, bptr);
284 /* handle replacement points */
285 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
287 #if defined(ENABLE_PROFILING)
290 /* FIXME there are still some constrcuts to copy in here */
292 #if defined(ENABLE_LSRA)
296 /* copy interface registers to their destination */
302 var = VAR(bptr->invars[len]);
303 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
304 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
305 M_ADRMOVE(REG_ATMP1_XPTR, d);
306 emit_store(jd, NULL, var, d);
309 assert((var->flags & INOUT));
313 /* walk through all instructions */
317 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
318 if (iptr->line != currentline) {
319 linenumbertable_list_entry_add(cd, iptr->line);
320 currentline = iptr->line;
323 MCODECHECK(1024); /* 1kB should be enough */
326 case ICMD_NOP: /* ... ==> ... */
327 case ICMD_POP: /* ..., value ==> ... */
328 case ICMD_POP2: /* ..., value, value ==> ... */
331 case ICMD_INLINE_START:
333 REPLACEMENT_POINT_INLINE_START(cd, iptr);
336 case ICMD_INLINE_BODY:
338 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
339 linenumbertable_list_entry_add_intern(cd, iptr);
340 linenumbertable_list_entry_add(cd, iptr->line);
343 case ICMD_INLINE_END:
345 linenumbertable_list_entry_add_inline(cd, iptr);
346 linenumbertable_list_entry_add(cd, iptr->line);
349 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
352 assert(VAROP(iptr->s1)->type == TYPE_ADR);
353 emit_nullpointer_check(cd, iptr, s1);
357 /* CONST **************************************************************/
358 case ICMD_ICONST: /* ... ==> ..., constant */
359 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
360 M_IMOV_IMM(iptr->sx.val.i, d);
361 emit_store_dst(jd, iptr, d);
364 case ICMD_LCONST: /* ... ==> ..., constant */
366 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
367 LCONST(iptr->sx.val.l, d);
368 emit_store_dst(jd, iptr, d);
371 case ICMD_FCONST: /* ... ==> ..., constant */
373 #if defined(ENABLE_SOFTFLOAT)
374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
375 M_IMOV_IMM(iptr->sx.val.i, d);
376 emit_store_dst(jd, iptr, d);
378 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
379 FCONST(iptr->sx.val.i, d);
380 emit_store_dst(jd, iptr, d);
384 case ICMD_DCONST: /* ... ==> ..., constant */
386 #if defined(ENABLE_SOFTFLOAT)
387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
388 LCONST(iptr->sx.val.l, d);
389 emit_store_dst(jd, iptr, d);
391 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
392 disp = dseg_add_double(cd, iptr->sx.val.d);
393 M_AMOV_IMM(0, REG_ATMP1);
395 M_DLD(d, REG_ATMP1, disp);
396 emit_store_dst(jd, iptr, d);
401 /* some long operations *********************************************/
402 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
403 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
404 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
405 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
406 M_INTMOVE(s2, REG_ITMP1);
407 M_IADD(s1, REG_ITMP1); /* low word */
408 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
409 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
410 M_INTMOVE(s2, REG_ITMP2);
411 M_IADDX(s1, REG_ITMP2); /* high word */
412 emit_store_dst(jd, iptr, d);
415 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
416 /* sx.val.l = constant */
417 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
418 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
421 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
423 s3 = iptr->sx.val.l & 0xffffffff;
424 M_INTMOVE(s1, REG_ITMP1);
425 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
427 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
428 M_LNGMOVE(REG_ITMP12_PACKED, d);
429 emit_store_dst(jd, iptr, d);
432 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
433 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
434 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
435 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
436 M_INTMOVE(s1, REG_ITMP1);
437 M_ISUB(s2, REG_ITMP1); /* low word */
438 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
439 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
440 M_INTMOVE(s1, REG_ITMP2);
441 M_ISUBX(s2, REG_ITMP2); /* high word */
442 emit_store_dst(jd, iptr, d);
445 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
446 /* sx.val.l = constant */
447 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
448 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
449 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
451 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
453 s3 = (-iptr->sx.val.l) & 0xffffffff;
454 M_INTMOVE(s1, REG_ITMP1);
455 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
457 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
458 M_LNGMOVE(REG_ITMP12_PACKED, d);
459 emit_store_dst(jd, iptr, d);
462 case ICMD_LNEG: /* ..., value ==> ..., - value */
463 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
465 M_LNGMOVE(s1, REG_ITMP12_PACKED);
466 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
467 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
468 M_LNGMOVE(REG_ITMP12_PACKED, d);
469 emit_store_dst(jd, iptr, d);
472 /* integer operations ************************************************/
473 case ICMD_INEG: /* ..., value ==> ..., - value */
475 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
476 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
477 M_INTMOVE(s1, REG_ITMP1);
479 M_INTMOVE(REG_ITMP1, d);
480 emit_store_dst(jd, iptr, d);
483 case ICMD_I2L: /* ..., value ==> ..., value */
485 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
486 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
487 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
489 M_ISET(GET_HIGH_REG(d));
491 M_ICLR(GET_HIGH_REG(d));
493 emit_store_dst(jd, iptr, d);
496 case ICMD_L2I: /* ..., value ==> ..., value */
498 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
499 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
501 emit_store_dst(jd, iptr, d);
503 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
506 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
508 emit_store_dst(jd, iptr, d);
511 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
514 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
516 emit_store_dst(jd, iptr, d);
519 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
524 emit_store_dst(jd, iptr, d);
529 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
532 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
534 M_INTMOVE(s2, REG_ITMP2);
535 M_IADD(s1, REG_ITMP2);
536 M_INTMOVE(REG_ITMP2, d);
537 emit_store_dst(jd, iptr, d);
540 /* s1.localindex = variable, sx.val.i = constant*/
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
547 M_INTMOVE(s1, REG_ITMP1);
548 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
549 M_INTMOVE(REG_ITMP1, d);
550 emit_store_dst(jd, iptr, d);
553 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
556 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
557 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
558 M_INTMOVE(s1, REG_ITMP1);
559 M_ISUB(s2, REG_ITMP1);
560 M_INTMOVE(REG_ITMP1, d);
561 emit_store_dst(jd, iptr, d);
564 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
565 /* sx.val.i = constant */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
569 M_INTMOVE(s1, REG_ITMP1);
570 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
571 M_INTMOVE(REG_ITMP1, d);
572 emit_store_dst(jd, iptr, d);
575 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
579 emit_arithmetic_check(cd, iptr, s2);
580 M_INTMOVE(s1, REG_ITMP1);
581 M_IDIV(s2, REG_ITMP1);
582 M_INTMOVE(REG_ITMP1, d);
583 emit_store_dst(jd, iptr, d);
586 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
589 M_INTMOVE(s1, REG_ITMP1);
593 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
595 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
596 M_ISSR(REG_ITMP2, REG_ITMP1);
597 M_INTMOVE(REG_ITMP1, d);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
603 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
605 emit_arithmetic_check(cd, iptr, s2);
607 M_ICMP_IMM(0x80000000, s1);
612 M_TPFL; /* hides the next instruction */
613 M_IREM(s2, s1, REG_ITMP3);
615 M_INTMOVE(REG_ITMP3, d);
617 emit_store_dst(jd, iptr, d);
620 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
624 M_IMOV(s1, REG_ITMP1);
628 M_IAND_IMM(iptr->sx.val.i, d);
630 M_BGE(2 + 2 + 6 + 2);
631 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
633 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
636 emit_store_dst(jd, iptr, d);
640 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
641 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
643 bte = iptr->sx.s23.s3.bte;
646 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
647 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
648 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
649 /* XXX could be optimized */
650 emit_arithmetic_check(cd, iptr, REG_ITMP3);
652 M_LST(s2, REG_SP, 2 * 4);
653 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
654 M_LST(s1, REG_SP, 0 * 4);
658 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
659 M_LNGMOVE(REG_RESULT_PACKED, d);
660 emit_store_dst(jd, iptr, d);
663 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
668 M_INTMOVE(s2, REG_ITMP2);
669 M_IMUL(s1, REG_ITMP2);
670 M_INTMOVE(REG_ITMP2, d);
671 emit_store_dst(jd, iptr, d);
674 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
675 /* sx.val.i = constant */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
678 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
679 M_IMUL(s1, REG_ITMP2);
680 M_INTMOVE(REG_ITMP2, d);
681 emit_store_dst(jd, iptr, d);
684 case ICMD_ISHL: /* ..., 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_ISSL(REG_ITMP2, REG_ITMP1);
693 M_INTMOVE(REG_ITMP1, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_ISHLCONST: /* ..., 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_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
707 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
708 M_ISSL(REG_ITMP2, REG_ITMP1);
710 M_INTMOVE(REG_ITMP1, d);
714 emit_store_dst(jd, iptr, d);
717 case ICMD_ISHR: /* ..., 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_ISSR(REG_ITMP2, REG_ITMP1);
726 M_INTMOVE(REG_ITMP1, d);
727 emit_store_dst(jd, iptr, d);
730 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
731 /* sx.val.i = constant */
733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
735 if (iptr->sx.val.i & 0x1f) {
736 M_INTMOVE(s1, REG_ITMP1)
737 if ((iptr->sx.val.i & 0x1f) <= 7) {
738 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
740 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
741 M_ISSR(REG_ITMP2, REG_ITMP1);
743 M_INTMOVE(REG_ITMP1, d);
747 emit_store_dst(jd, iptr, d);
750 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
755 M_INTMOVE(s1, REG_ITMP1);
756 M_INTMOVE(s2, REG_ITMP2);
757 M_IAND_IMM(0x1f, REG_ITMP2);
758 M_IUSR(REG_ITMP2, REG_ITMP1);
759 M_INTMOVE(REG_ITMP1, d);
760 emit_store_dst(jd, iptr, d);
763 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
764 /* sx.val.i = constant */
765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
767 if (iptr->sx.val.i & 0x1f) {
768 M_INTMOVE(s1, REG_ITMP1)
769 if ((iptr->sx.val.i & 0x1f) <= 7) {
770 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
772 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
773 M_IUSR(REG_ITMP2, REG_ITMP1);
775 M_INTMOVE(REG_ITMP1, d);
779 emit_store_dst(jd, iptr, d);
782 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
786 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
787 M_INTMOVE(s2, REG_ITMP2);
788 M_IAND(s1, REG_ITMP2);
789 M_INTMOVE(REG_ITMP2, d);
790 emit_store_dst(jd, iptr, d);
793 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
794 /* sx.val.i = constant */
796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
798 M_INTMOVE(s1, REG_ITMP1);
799 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
800 M_INTMOVE(REG_ITMP1, d);
801 emit_store_dst(jd, iptr, d);
804 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
807 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
808 M_INTMOVE(s2, REG_ITMP2);
809 M_IOR(s1, REG_ITMP2);
810 M_INTMOVE(REG_ITMP2, d);
811 emit_store_dst(jd, iptr, d);
814 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
815 /* sx.val.i = constant */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
818 M_INTMOVE(s1, REG_ITMP1);
819 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
820 M_INTMOVE(REG_ITMP1, d);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
827 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828 M_INTMOVE(s2, REG_ITMP2);
829 M_IXOR(s1, REG_ITMP2);
830 M_INTMOVE(REG_ITMP2, d);
831 emit_store_dst(jd, iptr, d);
834 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
835 /* sx.val.i = constant */
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
838 M_INTMOVE(s1, REG_ITMP1);
839 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
840 M_INTMOVE(REG_ITMP1, d);
841 emit_store_dst(jd, iptr, d);
844 /* floating point operations ******************************************/
845 #if !defined(ENABLE_SOFTFLOAT)
846 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
848 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
849 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
853 M_BFUN(14); /* result is -1, branch to end */
854 M_BFLT(10); /* result is -1, branch to end */
856 M_BFEQ(4) /* result is 0, branch to end */
858 emit_store_dst(jd, iptr, d);
861 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
863 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
864 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
868 M_BFUN(16); /* result is +1, branch to end */
869 M_BFGT(14); /* result is +1, branch to end */
871 M_BFEQ(8) /* result is 0, branch to end */
873 emit_store_dst(jd, iptr, d);
876 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
877 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
878 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
879 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
880 M_FLTMOVE(s2, REG_FTMP2);
881 M_FMUL(s1, REG_FTMP2);
882 M_FLTMOVE(REG_FTMP2, d);
883 emit_store_dst(jd, iptr, d);
886 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
887 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
888 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
889 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
890 M_DBLMOVE(s2, REG_FTMP2);
891 M_DMUL(s1, REG_FTMP2);
892 M_DBLMOVE(REG_FTMP2, d);
893 emit_store_dst(jd, iptr, d);
896 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
897 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
898 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
899 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
900 M_FLTMOVE(s1, REG_FTMP1);
901 M_FDIV(s2, REG_FTMP1);
902 M_FLTMOVE(REG_FTMP1, d);
903 emit_store_dst(jd, iptr, d);
906 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
907 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
908 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
909 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
910 M_DBLMOVE(s1, REG_FTMP1);
911 M_DDIV(s2, REG_FTMP1);
912 M_DBLMOVE(REG_FTMP1, d);
913 emit_store_dst(jd, iptr, d);
916 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
917 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
918 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
919 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
920 M_FLTMOVE(s2, REG_FTMP2);
921 M_FADD(s1, REG_FTMP2);
922 M_FLTMOVE(REG_FTMP2, d);
923 emit_store_dst(jd, iptr, d);
926 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
927 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
928 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
929 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
930 M_DBLMOVE(s2, REG_FTMP2);
931 M_DADD(s1, REG_FTMP2);
932 M_DBLMOVE(REG_FTMP2, d);
933 emit_store_dst(jd, iptr, d);
936 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
937 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
938 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
939 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
940 M_FLTMOVE(s1, REG_FTMP1);
941 M_FSUB(s2, REG_FTMP1);
942 M_FLTMOVE(REG_FTMP1, d);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
947 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
948 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
949 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
950 M_DBLMOVE(s1, REG_FTMP1);
951 M_DSUB(s2, REG_FTMP1);
952 M_DBLMOVE(REG_FTMP1, d);
953 emit_store_dst(jd, iptr, d);
956 case ICMD_F2D: /* ..., value ==> ..., (double) value */
957 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
958 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
960 emit_store_dst(jd, iptr, d);
963 case ICMD_D2F: /* ..., value ==> ..., (float) value */
964 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
965 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
967 emit_store_dst(jd, iptr, d);
970 case ICMD_FNEG: /* ..., value ==> ..., - value */
971 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
972 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
974 emit_store_dst(jd, iptr, d);
977 case ICMD_DNEG: /* ..., value ==> ..., - value */
978 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
979 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
981 emit_store_dst(jd, iptr, d);
986 /* load/store/copy/move operations ************************************/
988 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
989 case ICMD_ALOAD: /* s1 = local variable */
993 case ICMD_ISTORE: /* ..., value ==> ... */
1000 emit_copy(jd, iptr);
1005 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1006 emit_copy(jd, iptr);
1010 case ICMD_ACONST: /* ... ==> ..., constant */
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1013 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1014 constant_classref *cr = iptr->sx.val.c.ref;;
1015 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1018 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1020 emit_store_dst(jd, iptr, d);
1022 /* BRANCH *************************************************************/
1024 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1026 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1027 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1029 #ifdef ENABLE_VERIFIER
1030 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1031 unresolved_class *uc = iptr->sx.s23.s2.uc;
1033 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1035 #endif /* ENABLE_VERIFIER */
1036 M_JSR_PCREL(2); /* get current PC */
1039 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1044 case ICMD_GOTO: /* ... ==> ... */
1045 case ICMD_RET: /* ... ==> ... */
1047 emit_br(cd, iptr->dst.block);
1051 case ICMD_JSR: /* ... ==> ... */
1053 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1059 case ICMD_IFNULL: /* ..., value ==> ... */
1060 case ICMD_IFNONNULL:
1061 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1062 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1064 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1072 case ICMD_IFEQ: /* ..., value ==> ... */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 assert (VAROP(iptr->s1)->type == TYPE_INT);
1076 M_ICMP_IMM(iptr->sx.val.i, s1);
1077 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1080 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1081 case ICMD_IF_ICMPNE:
1082 case ICMD_IF_ICMPLT:
1083 case ICMD_IF_ICMPGT:
1084 case ICMD_IF_ICMPLE:
1085 case ICMD_IF_ICMPGE:
1087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1088 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1090 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1093 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1094 case ICMD_IF_ACMPNE:
1096 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1097 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1099 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1103 /* MEMORY *************************************************************/
1105 case ICMD_GETSTATIC: /* ... ==> ..., value */
1107 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1108 uf = iptr->sx.s23.s3.uf;
1109 fieldtype = uf->fieldref->parseddesc.fd->type;
1112 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1115 fi = iptr->sx.s23.s3.fmiref->p.field;
1116 fieldtype = fi->type;
1117 disp = (intptr_t) fi->value;
1119 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1120 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1125 M_AMOV_IMM(disp, REG_ATMP1);
1126 switch (fieldtype) {
1127 #if defined(ENABLE_SOFTFLOAT)
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1132 M_ILD(d, REG_ATMP1, 0);
1135 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1136 M_ALD(d, REG_ATMP1, 0);
1138 #if defined(ENABLE_SOFTFLOAT)
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1143 M_LLD(d, REG_ATMP1, 0);
1145 #if !defined(ENABLE_SOFTFLOAT)
1147 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1148 M_FLD(d, REG_ATMP1, 0);
1151 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1152 M_DLD(d, REG_ATMP1, 0);
1156 emit_store_dst(jd, iptr, d);
1159 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1161 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1162 uf = iptr->sx.s23.s3.uf;
1163 fieldtype = uf->fieldref->parseddesc.fd->type;
1166 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1169 fi = iptr->sx.s23.s3.fmiref->p.field;
1170 fieldtype = fi->type;
1171 disp = (intptr_t) fi->value;
1173 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1174 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1178 M_AMOV_IMM(disp, REG_ATMP1);
1179 switch (fieldtype) {
1180 #if defined(ENABLE_SOFTFLOAT)
1184 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1185 M_IST(s1, REG_ATMP1, 0);
1187 #if defined(ENABLE_SOFTFLOAT)
1191 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1192 M_LST(s1, REG_ATMP1, 0);
1195 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1196 M_AST(s1, REG_ATMP1, 0);
1198 #if !defined(ENABLE_SOFTFLOAT)
1200 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1201 M_FST(s1, REG_ATMP1, 0);
1204 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1205 M_DST(s1, REG_ATMP1, 0);
1212 case ICMD_GETFIELD: /* ... ==> ..., value */
1214 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1216 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1217 uf = iptr->sx.s23.s3.uf;
1218 fieldtype = uf->fieldref->parseddesc.fd->type;
1221 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1224 fi = iptr->sx.s23.s3.fmiref->p.field;
1225 fieldtype = fi->type;
1229 /* implicit null-pointer check */
1230 switch (fieldtype) {
1231 #if defined(ENABLE_SOFTFLOAT)
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1238 #if defined(ENABLE_SOFTFLOAT)
1242 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1246 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1249 #if !defined(ENABLE_SOFTFLOAT)
1251 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1255 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1260 emit_store_dst(jd, iptr, d);
1263 case ICMD_PUTFIELD: /* ..., value ==> ... */
1265 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1267 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1268 uf = iptr->sx.s23.s3.uf;
1269 fieldtype = uf->fieldref->parseddesc.fd->type;
1273 fi = iptr->sx.s23.s3.fmiref->p.field;
1274 fieldtype = fi->type;
1278 if (IS_INT_LNG_TYPE(fieldtype)) {
1279 if (IS_2_WORD_TYPE(fieldtype)) {
1280 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1282 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1285 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1288 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1289 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1291 /* implicit null-pointer check */
1292 switch (fieldtype) {
1293 #if defined(ENABLE_SOFTFLOAT)
1297 M_IST(s2, s1, disp);
1300 #if defined(ENABLE_SOFTFLOAT)
1304 M_LST(s2, s1, disp);
1307 M_AST(s2, s1, disp);
1309 #if !defined(ENABLE_SOFTFLOAT)
1311 M_FST(s2, s1, disp);
1314 M_DST(s2, s1, disp);
1320 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1322 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1323 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1324 /* implicit null-pointer check */
1325 M_ILD(d, s1, OFFSET(java_array_t, size));
1326 emit_store_dst(jd, iptr, d);
1329 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1331 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1332 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1333 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1334 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1335 M_INTMOVE(s2, REG_ITMP2);
1336 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1337 M_ADRMOVE(s1, REG_ATMP1);
1338 M_AADDINT(REG_ITMP2, REG_ATMP1);
1339 /* implicit null-pointer check */
1340 M_LBZX(REG_ATMP1, d);
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1347 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1348 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1349 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1350 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1351 M_INTMOVE(s2, REG_ITMP2);
1352 M_ISSL_IMM(1, REG_ITMP2);
1353 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1354 M_ADRMOVE(s1, REG_ATMP1);
1355 M_AADDINT(REG_ITMP2, REG_ATMP1);
1356 /* implicit null-pointer check */
1357 M_LHZX(REG_ATMP1, d);
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1364 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1365 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1366 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1367 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1368 M_INTMOVE(s2, REG_ITMP2);
1369 M_ISSL_IMM(1, REG_ITMP2);
1370 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1371 M_ADRMOVE(s1, REG_ATMP1);
1372 M_AADDINT(REG_ITMP2, REG_ATMP1);
1374 /* implicit null-pointer check */
1375 M_LHZX(REG_ATMP1, d);
1377 emit_store_dst(jd, iptr, d);
1380 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1382 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1383 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1384 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1385 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1386 M_INTMOVE(s2, REG_ITMP2);
1387 M_ISSL_IMM(2, REG_ITMP2);
1388 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1389 M_ADRMOVE(s1, REG_ATMP1);
1390 M_AADDINT(REG_ITMP2, REG_ATMP1);
1391 /* implicit null-pointer check */
1392 M_LWZX(REG_ATMP1, d);
1393 emit_store_dst(jd, iptr, d);
1396 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1397 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1398 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1400 /* implicit null-pointer check */
1401 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1402 M_INTMOVE(s2, REG_ITMP1);
1403 M_ISSL_IMM(3, REG_ITMP1);
1404 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1405 M_ADRMOVE(s1, REG_ATMP1);
1406 M_AADDINT(REG_ITMP1, REG_ATMP1);
1407 /* implicit null-pointer check */
1408 M_LLD(d, REG_ATMP1, 0);
1409 emit_store_dst(jd, iptr, d);
1412 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1413 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1415 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1416 M_INTMOVE(s2, REG_ITMP2);
1417 M_ISSL_IMM(2, REG_ITMP2);
1418 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1419 M_ADRMOVE(s1, REG_ATMP1);
1420 M_AADDINT(REG_ITMP2, REG_ATMP1);
1421 /* implicit null-pointer check */
1422 #if !defined(ENABLE_SOFTFLOAT)
1423 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1424 M_FLD(d, REG_ATMP1, 0);
1426 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1427 M_LWZX(REG_ATMP1, d);
1429 emit_store_dst(jd, iptr, d);
1432 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1433 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1434 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1435 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1436 M_INTMOVE(s2, REG_ITMP2);
1437 M_ISSL_IMM(3, REG_ITMP2);
1438 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1439 M_ADRMOVE(s1, REG_ATMP1);
1440 M_AADDINT(REG_ITMP2, REG_ATMP1);
1441 /* implicit null-pointer check */
1442 #if !defined(ENABLE_SOFTFLOAT)
1443 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1444 M_DLD(d, REG_ATMP1, 0);
1446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1447 M_LLD(d, REG_ATMP1, 0);
1449 emit_store_dst(jd, iptr, d);
1452 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1453 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1454 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1456 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1457 M_INTMOVE(s2, REG_ITMP2);
1458 M_ISSL_IMM(2, REG_ITMP2);
1459 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1460 M_ADRMOVE(s1, REG_ATMP1);
1461 M_AADDINT(REG_ITMP2, REG_ATMP1);
1463 /* implicit null-pointer check */
1464 M_LAX(REG_ATMP1, d);
1465 emit_store_dst(jd, iptr, d);
1469 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1470 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1472 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1473 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1474 M_INTMOVE(s2, REG_ITMP2);
1475 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1476 M_ADRMOVE(s1, REG_ATMP1);
1477 M_AADDINT(REG_ITMP2, REG_ATMP1);
1478 /* implicit null-pointer check */
1479 M_STBX(REG_ATMP1, s3);
1482 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1485 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1486 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1487 M_INTMOVE(s2, REG_ITMP2);
1488 M_ISSL_IMM(1, REG_ITMP2);
1489 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1490 M_ADRMOVE(s1, REG_ATMP1);
1491 M_AADDINT(REG_ITMP2, REG_ATMP1);
1492 /* implicit null-pointer check */
1493 M_STHX(REG_ATMP1, s3);
1496 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1498 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1499 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1500 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1501 M_INTMOVE(s2, REG_ITMP2);
1502 M_ISSL_IMM(1, REG_ITMP2);
1503 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1504 M_ADRMOVE(s1, REG_ATMP1);
1505 M_AADDINT(REG_ITMP2, REG_ATMP1);
1506 /* implicit null-pointer check */
1507 M_STHX(REG_ATMP1, s3);
1510 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1511 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1512 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1513 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1514 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1515 M_INTMOVE(s2, REG_ITMP2);
1516 M_ISSL_IMM(2, REG_ITMP2);
1517 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1518 M_ADRMOVE(s1, REG_ATMP1);
1519 M_AADDINT(REG_ITMP2, REG_ATMP1);
1520 /* implicit null-pointer check */
1521 M_STWX(REG_ATMP1, s3);
1524 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1525 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1527 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1529 M_INTMOVE(s2, REG_ITMP1);
1530 M_ISSL_IMM(3, REG_ITMP1);
1531 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1532 M_ADRMOVE(s1, REG_ATMP1);
1533 M_AADDINT(REG_ITMP1, REG_ATMP1);
1534 /* implicit null-pointer check */
1535 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1536 M_LST(s3, REG_ATMP1, 0);
1539 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1540 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1541 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1542 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1543 M_INTMOVE(s2, REG_ITMP2);
1544 M_ISSL_IMM(2, REG_ITMP2);
1545 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1546 M_ADRMOVE(s1, REG_ATMP1);
1547 M_AADDINT(REG_ITMP2, REG_ATMP1);
1548 /* implicit null-pointer check */
1549 #if !defined(ENABLE_SOFTFLOAT)
1550 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1551 M_FST(s3, REG_ATMP1, 0);
1553 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1554 M_STWX(REG_ATMP1, s3);
1558 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1561 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1562 M_INTMOVE(s2, REG_ITMP2);
1563 M_ISSL_IMM(3, REG_ITMP2);
1564 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1565 M_ADRMOVE(s1, REG_ATMP1);
1566 M_AADDINT(REG_ITMP2, REG_ATMP1);
1567 /* implicit null-pointer check */
1568 #if !defined(ENABLE_SOFTFLOAT)
1569 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1570 M_DST(s3, REG_ATMP1, 0);
1572 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1573 /* implicit null-pointer check */
1574 M_LST(s3, REG_ATMP1, 0);
1578 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1580 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1581 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1582 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1583 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1585 /* XXX what if array is NULL */
1586 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1588 M_AST(s1, REG_SP, 0*4);
1589 M_AST(s3, REG_SP, 1*4);
1590 M_JSR_IMM(BUILTIN_FAST_canstore);
1591 emit_arraystore_check(cd, iptr);
1593 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1594 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1595 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1596 M_INTMOVE(s2, REG_ITMP1);
1597 M_ISSL_IMM(2, REG_ITMP1);
1598 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1599 M_ADRMOVE(s1, REG_ATMP1);
1600 M_AADDINT(REG_ITMP1, REG_ATMP1);
1601 /* implicit null-pointer check */
1602 M_STAX(REG_ATMP1, s3);
1607 /* METHOD INVOCATION *********************************************************/
1608 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1609 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1611 bte = iptr->sx.s23.s3.bte;
1615 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1616 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1617 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1618 case ICMD_INVOKEINTERFACE:
1619 REPLACEMENT_POINT_INVOKE(cd, iptr);
1621 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1623 um = iptr->sx.s23.s3.um;
1624 md = um->methodref->parseddesc.md;
1627 lm = iptr->sx.s23.s3.fmiref->p.method;
1629 md = lm->parseddesc;
1632 s3 = md->paramcount;
1634 MCODECHECK((s3 << 1) + 64);
1636 /* copy arguments to stack */
1637 for (s3 = s3 - 1; s3 >= 0; s3--) {
1638 var = VAR(iptr->sx.s23.s2.args[s3]);
1639 /* already preallocated */
1640 if (var->flags & PREALLOC) continue;
1642 if (!md->params[s3].inmemory) assert(0);
1644 switch (var->type) {
1645 #if defined(ENABLE_SOFTFLOAT)
1649 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1650 M_LST(d, REG_SP, md->params[s3].regoff);
1652 #if defined(ENABLE_SOFTFLOAT)
1656 d = emit_load(jd, iptr, var, REG_ITMP1);
1657 M_IST(d, REG_SP, md->params[s3].regoff);
1660 d = emit_load(jd, iptr, var, REG_ATMP1);
1661 M_AST(d, REG_SP, md->params[s3].regoff);
1663 #if !defined(ENABLE_SOFTFLOAT)
1665 d = emit_load(jd, iptr, var, REG_FTMP1);
1666 M_FST(d, REG_SP, md->params[s3].regoff);
1669 d = emit_load(jd, iptr, var, REG_FTMP1);
1670 M_DST(d, REG_SP, md->params[s3].regoff);
1678 /* arguments in place now */
1681 if (bte->stub == NULL)
1682 disp = (ptrint) bte->fp;
1684 disp = (ptrint) bte->stub;
1685 d = md->returntype.type;
1688 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1691 case ICMD_INVOKESPECIAL:
1692 /* adress register for sure */
1693 M_ALD(REG_ATMP1, REG_SP, 0);
1694 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1696 case ICMD_INVOKESTATIC:
1698 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1700 M_AMOV_IMM(disp, REG_ATMP1);
1702 disp = lm->stubroutine;
1703 M_AMOV_IMM(disp, REG_ATMP1);
1706 /* generate the actual call */
1708 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1712 case ICMD_INVOKEVIRTUAL:
1714 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1717 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1719 /* load object pointer (==argument 0) */
1720 M_ALD(REG_ATMP1, REG_SP, 0);
1721 /* implicit null-pointer check */
1722 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1723 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1724 /* generate the actual call */
1727 case ICMD_INVOKEINTERFACE:
1729 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1734 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
1735 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1737 /* load object pointer (==argument 0) */
1738 M_ALD(REG_ATMP1, REG_SP, 0);
1740 /* implicit null-pointer check */
1741 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1742 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1743 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1745 /* generate the actual call */
1747 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1751 } /* switch (iptr->opc) */
1753 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1754 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1756 /* store return value */
1757 d = md->returntype.type;
1760 case TYPE_VOID: break;
1761 #if defined(ENABLE_SOFTFLOAT)
1765 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1766 M_INTMOVE(REG_RESULT, s1);
1768 #if defined(ENABLE_SOFTFLOAT)
1772 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1773 M_LNGMOVE(REG_RESULT_PACKED, s1);
1776 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1777 /* all stuff is returned in %d0 */
1778 M_INT2ADRMOVE(REG_RESULT, s1);
1780 #if !defined(ENABLE_SOFTFLOAT)
1782 * for BUILTINS float values are returned in %d0,%d1
1783 * within cacao we use %fp0 for that.
1786 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1787 if (iptr->opc == ICMD_BUILTIN) {
1788 M_INT2FLTMOVE(REG_FRESULT, s1);
1790 M_FLTMOVE(REG_FRESULT, s1);
1794 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1795 if (iptr->opc == ICMD_BUILTIN) {
1796 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1797 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1799 M_DBLMOVE(REG_FRESULT, s1);
1806 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1807 break; /* ICMD_INVOKE* */
1809 #if defined(ENABLE_SOFTFLOAT)
1812 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1814 REPLACEMENT_POINT_RETURN(cd, iptr);
1815 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1816 M_INTMOVE(s1, REG_RESULT);
1817 goto nowperformreturn;
1819 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1821 REPLACEMENT_POINT_RETURN(cd, iptr);
1822 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1823 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1824 M_ADR2INTMOVE(s1, REG_RESULT);
1826 #ifdef ENABLE_VERIFIER
1827 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1828 unresolved_class *uc = iptr->sx.s23.s2.uc;
1830 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1832 #endif /* ENABLE_VERIFIER */
1833 goto nowperformreturn;
1835 #if defined(ENABLE_SOFTFLOAT)
1838 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1839 REPLACEMENT_POINT_RETURN(cd, iptr);
1840 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1841 M_LNGMOVE(s1, REG_RESULT_PACKED);
1842 goto nowperformreturn;
1844 #if !defined(ENABLE_SOFTFLOAT)
1845 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1846 REPLACEMENT_POINT_RETURN(cd, iptr);
1847 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1848 M_FLTMOVE(s1, REG_FRESULT);
1849 goto nowperformreturn;
1852 REPLACEMENT_POINT_RETURN(cd, iptr);
1853 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1854 M_DBLMOVE(s1, REG_FRESULT);
1855 goto nowperformreturn;
1859 case ICMD_RETURN: /* ... ==> ... */
1861 REPLACEMENT_POINT_RETURN(cd, iptr);
1867 p = cd->stackframesize;
1869 /* call trace function */
1870 #if !defined(NDEBUG)
1871 emit_verbosecall_exit(jd);
1874 #if defined(ENABLE_THREADS)
1875 /* call lock_monitor_exit */
1876 if (checksync && code_is_synchronized(code)) {
1877 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1879 /* we need to save the proper return value */
1880 /* we do not care for the long -> doubel convert space here */
1881 switch (iptr->opc) {
1882 #if defined(ENABLE_SOFTFLOAT)
1886 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1888 #if defined(ENABLE_SOFTFLOAT)
1893 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1895 #if !defined(ENABLE_SOFTFLOAT)
1897 M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1900 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1905 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1906 M_JSR_IMM(LOCK_monitor_exit);
1908 /* and now restore the proper return value */
1909 switch (iptr->opc) {
1911 #if defined(ENABLE_SOFTFLOAT)
1915 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1917 #if defined(ENABLE_SOFTFLOAT)
1922 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1924 #if !defined(ENABLE_SOFTFLOAT)
1926 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1929 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1937 /* restore return address */
1939 if (!code_is_leafmethod(code)) {
1940 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1941 may have a displacement overflow. */
1943 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1947 /* restore saved registers */
1949 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1950 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1952 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1953 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1955 #if !defined(ENABLE_SOFTFLOAT)
1956 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1957 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1960 /* deallocate stack */
1961 M_AADD_IMM(cd->stackframesize, REG_SP);
1967 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1968 /* val.a: (classinfo*) superclass */
1970 /* superclass is an interface:
1972 * return (sub != NULL) &&
1973 * (sub->vftbl->interfacetablelength > super->index) &&
1974 * (sub->vftbl->interfacetable[-super->index] != NULL);
1976 * superclass is a class:
1978 * return ((sub != NULL) && (0
1979 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1980 * super->vftbl->diffvall));
1987 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1992 super = iptr->sx.s23.s3.c.cls;
1993 superindex = super->index;
1996 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1997 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1999 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2000 assert(VAROP(iptr->dst)->type == TYPE_INT);
2004 /* if class is not resolved, check which code to call */
2006 if (super == NULL) {
2008 emit_label_beq(cd, BRANCH_LABEL_1);
2010 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2012 M_IMOV_IMM32(0, REG_ITMP3);
2013 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2014 emit_label_beq(cd, BRANCH_LABEL_2);
2017 /* interface instanceof code */
2019 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2020 if (super == NULL) {
2021 patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2024 emit_label_beq(cd, BRANCH_LABEL_3);
2027 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2028 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2029 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
2032 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
2038 emit_label_br(cd, BRANCH_LABEL_4);
2040 emit_label(cd, BRANCH_LABEL_3);
2043 /* class instanceof code */
2045 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2046 if (super == NULL) {
2047 emit_label(cd, BRANCH_LABEL_2);
2049 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2050 M_AMOV_IMM(0, REG_ATMP2);
2052 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2054 emit_label_beq(cd, BRANCH_LABEL_5);
2057 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2059 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2060 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2061 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2063 M_ISUB(REG_ITMP3, REG_ITMP1);
2064 M_ICMP(REG_ITMP2, REG_ITMP1);
2067 M_TPFW; /* overlaps next instruction */
2071 emit_label(cd, BRANCH_LABEL_5);
2074 if (super == NULL) {
2075 emit_label(cd, BRANCH_LABEL_1);
2076 emit_label(cd, BRANCH_LABEL_4);
2079 emit_store_dst(jd, iptr, d);
2083 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2084 /* val.a: (classinfo*) superclass */
2086 /* superclass is an interface:
2088 * OK if ((sub == NULL) ||
2089 * (sub->vftbl->interfacetablelength > super->index) &&
2090 * (sub->vftbl->interfacetable[-super->index] != NULL));
2092 * superclass is a class:
2094 * OK if ((sub == NULL) || (0
2095 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2096 * super->vftbl->diffvall));
2099 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2100 /* object type cast-check */
2105 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2110 super = iptr->sx.s23.s3.c.cls;
2111 superindex = super->index;
2114 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2115 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2117 /* if class is not resolved, check which code to call */
2119 if (super == NULL) {
2121 emit_label_beq(cd, BRANCH_LABEL_1);
2123 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2125 M_IMOV_IMM32(0, REG_ITMP2);
2126 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2127 emit_label_beq(cd, BRANCH_LABEL_2);
2130 /* interface checkcast code */
2132 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2133 if (super == NULL) {
2134 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2137 emit_label_beq(cd, BRANCH_LABEL_3);
2140 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2141 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2143 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2145 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2147 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2149 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2152 emit_label_br(cd, BRANCH_LABEL_4);
2154 emit_label(cd, BRANCH_LABEL_3);
2157 /* class checkcast code */
2159 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2160 if (super == NULL) {
2161 emit_label(cd, BRANCH_LABEL_2);
2163 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2164 M_AMOV_IMM(0, REG_ATMP3);
2166 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2168 emit_label_beq(cd, BRANCH_LABEL_5);
2171 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2173 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2174 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2175 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2177 M_ISUB(REG_ITMP1, REG_ITMP3);
2178 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2180 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2183 emit_label(cd, BRANCH_LABEL_5);
2186 if (super == NULL) {
2187 emit_label(cd, BRANCH_LABEL_1);
2188 emit_label(cd, BRANCH_LABEL_4);
2191 d = codegen_reg_of_dst(jd, iptr, s1);
2193 /* array type cast-check */
2195 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2197 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2198 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2199 M_AMOV_IMM(0, REG_ATMP1);
2201 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2206 M_JSR_IMM(BUILTIN_arraycheckcast);
2207 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2209 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2212 d = codegen_reg_of_dst(jd, iptr, s1);
2214 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2216 emit_store_dst(jd, iptr, d);
2219 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2222 branch_target_t *table;
2224 table = iptr->dst.table;
2226 l = iptr->sx.s23.s2.tablelow;
2227 i = iptr->sx.s23.s3.tablehigh;
2229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2230 M_INTMOVE(s1, REG_ITMP1);
2231 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2236 M_ICMP_IMM(i - 1, REG_ITMP1);
2237 emit_bugt(cd, table[0].block);
2239 /* build jump table top down and use address of lowest entry */
2243 dseg_add_target(cd, table->block);
2247 /* length of dataseg after last dseg_add_target is used by load */
2248 M_AMOV_IMM(0, REG_ATMP2);
2251 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2252 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2253 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2254 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2261 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2264 lookup_target_t *lookup;
2266 lookup = iptr->dst.lookup;
2268 i = iptr->sx.s23.s2.lookupcount;
2270 MCODECHECK((i<<2)+8);
2271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2274 M_ICMP_IMM(lookup->value, s1);
2275 emit_beq(cd, lookup->target.block);
2279 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2284 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2286 /* check for negative sizes and copy sizes to stack if necessary */
2287 MCODECHECK((iptr->s1.argcount << 1) + 64);
2289 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2290 var = VAR(iptr->sx.s23.s2.args[s1]);
2292 /* Already Preallocated? */
2293 if (!(var->flags & PREALLOC)) {
2294 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2295 M_IST(s2, REG_SP, (s1 + 3) * 4);
2299 /* a0 = dimension count */
2300 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2301 M_IST(REG_ITMP1, REG_SP, 0*4);
2303 /* a1 = arraydescriptor */
2304 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2305 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2306 M_AMOV_IMM(0, REG_ATMP1);
2308 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2310 M_AST(REG_ATMP1, REG_SP, 1*4);
2312 /* a2 = pointer to dimensions = stack pointer */
2313 M_AMOV(REG_SP, REG_ATMP1);
2314 M_AADD_IMM(3*4, REG_ATMP1);
2315 M_AST(REG_ATMP1, REG_SP, 2*4);
2317 M_JSR_IMM(BUILTIN_multianewarray);
2319 /* check for exception before result assignment */
2320 emit_exception_check(cd, iptr);
2322 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2323 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2324 M_INT2ADRMOVE(REG_RESULT, d);
2325 emit_store_dst(jd, iptr, d);
2331 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2332 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2335 /* M_TPF; */ /* nop after each ICMD */
2336 } /* for each instruction */
2338 /* At the end of a basic block we may have to append some nops,
2339 because the patcher stub calling code might be longer than the
2340 actual instruction. So codepatching does not change the
2341 following block unintentionally. */
2343 if (cd->mcodeptr < cd->lastmcodeptr) {
2344 while (cd->mcodeptr < cd->lastmcodeptr) {
2350 } /* if (btpre->flags >= BBREACHED) */
2351 } /* for each basic block */
2353 /* generate stubs */
2354 emit_patcher_traps(jd);
2359 /* codegen_emit_stub_native ****************************************************
2361 Emits a stub routine which calls a native method.
2363 *******************************************************************************/
2365 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2374 /* get required compiler data */
2383 /* calc stackframe size */
2384 cd->stackframesize =
2385 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2386 sizeof(localref_table) / SIZEOF_VOID_P +
2388 1 + /* functionptr */
2389 4; /* args for codegen_start_native_call */
2391 /* create method header */
2392 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2393 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2394 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2395 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2396 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2399 M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
2401 /* put arguments for codegen_start_native_call onto stack */
2402 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2404 M_AMOV(REG_SP, REG_ATMP1);
2405 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2407 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2408 dseg_adddata(cd); /* this patches it */
2410 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2412 M_JSR_IMM(codegen_start_native_call);
2414 /* remember class argument */
2415 if (m->flags & ACC_STATIC)
2416 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2418 /* copy arguments into stackframe */
2419 for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) {
2420 t = md->paramtypes[i].type;
2421 /* all arguments via stack */
2422 assert(md->params[i].inmemory);
2424 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
2425 s2 = nmd->params[j].regoff;
2427 /* simply copy argument stack */
2428 M_ILD(REG_ITMP1, REG_SP, s1);
2429 M_IST(REG_ITMP1, REG_SP, s2);
2430 if (IS_2_WORD_TYPE(t)) {
2431 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2432 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2436 /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
2437 if (m->flags & ACC_NATIVE) {
2438 /* for static function class as second arg */
2439 if (m->flags & ACC_STATIC)
2440 M_AST(REG_ATMP3, REG_SP, 1 * 4);
2442 /* env ist first argument */
2443 M_AMOV_IMM(VM_get_jnienv(), REG_ATMP1);
2444 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2447 /* call the native function */
2448 M_AMOV_IMM(f, REG_ATMP2);
2451 /* save return value */
2452 switch (md->returntype.type) {
2453 case TYPE_VOID: break;
2455 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2458 M_IST(REG_D1, REG_SP, 2 * 8);
2464 M_IST(REG_D0, REG_SP, 2 * 8); /* XXX can this be correct ? */
2470 /* remove native stackframe info */
2471 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2473 M_AMOV(REG_SP, REG_ATMP1);
2474 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2476 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2477 dseg_adddata(cd); /* this patches it */
2479 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2481 M_JSR_IMM(codegen_finish_native_call);
2483 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2484 /* restore return value */
2485 switch (md->returntype.type) {
2486 case TYPE_VOID: break;
2489 case TYPE_LNG: M_ILD(REG_D1, REG_SP, 2 * 8);
2494 M_ILD(REG_D0, REG_SP, 2 * 8); /* XXX */
2499 #if !defined(ENABLE_SOFTFLOAT)
2500 /* additionally load values into floating points registers
2501 * as cacao jit code expects them there */
2502 switch (md->returntype.type) {
2504 M_FLD(REG_D0, REG_SP, 2 * 8);
2507 M_DLD(REG_D0, REG_SP, 2 * 8); /* XXX */
2511 /* restore saved registers */
2513 M_AADD_IMM(cd->stackframesize*8, REG_SP);
2514 /* check for exception */
2519 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2521 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2522 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2523 M_JMP_IMM(asm_handle_nat_exception);
2525 /* should never be reached from within jit code*/
2531 * These are local overrides for various environment variables in Emacs.
2532 * Please do not remove this and leave it at the end of the file, where
2533 * Emacs will automagically detect them.
2534 * ---------------------------------------------------------------------
2537 * indent-tabs-mode: t
2541 * vim:noexpandtab:sw=4:ts=4: