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.h"
46 #include "vm/global.h"
47 #include "vm/stringlocal.h"
50 #include "vm/jit/asmpart.h"
51 #include "vm/jit/codegen-common.h"
52 #include "vm/jit/patcher-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/linenumbertable.h"
55 #include "vm/jit/emit-common.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/abi.h"
58 #include "vm/jit/parse.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
61 #include "vm/jit/stacktrace.h"
62 #include "vm/jit/trap.h"
64 #include "vmcore/loader.h"
65 #include "vmcore/options.h"
66 #include "vmcore/utf8.h"
69 bool codegen_emit(jitdata *jd)
75 s4 len, s1, s2, s3, d, disp;
80 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
81 unresolved_method *um;
82 builtintable_entry *bte;
89 /* get required compiler data */
96 /* prevent compiler warnings */
104 /* save calle saved registers */
105 s4 savedregs_num = 0;
107 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
108 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
109 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
111 cd->stackframesize = rd->memuse + savedregs_num;
113 /* we always add 2 stack slots.
114 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
115 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
116 * on the other hand we could use 2 words when a builtin returns a doulbe which are
117 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
118 * so we always _need_ at least 2 slots, and this keeps the code simple */
119 cd->stackframesize += 2;
121 cd->stackframesize *= 8; /* we use 8 byte stack slots */
124 #if defined(ENABLE_THREADS)
125 /* we need additional space to save argument of monitor_enter */
126 if (checksync && code_is_synchronized(code)) {
127 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
128 cd->stackframesize += 2;
130 cd->stackframesize += 1;
136 /* create method header */
137 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
138 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
140 code->synchronizedoffset = rd->memuse * 8;
142 /* REMOVEME: We still need it for exception handling in assembler. */
144 if (code_is_leafmethod(code))
145 (void) dseg_add_unique_s4(cd, 1);
147 (void) dseg_add_unique_s4(cd, 0);
149 /* XXX we use the IntSave a split field for the adr now */
150 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
151 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
153 #if defined(ENABLE_PROFILING)
158 emit_verbosecall_enter(jd);
160 /* create stack frame */
161 M_AADD_IMM(-(cd->stackframesize), REG_SP);
163 /* save used callee saved registers */
164 p = cd->stackframesize;
165 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
166 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
168 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
169 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
171 #if !defined(ENABLE_SOFTFLOAT)
172 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
173 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
176 assert(FLT_SAV_CNT == 0);
177 assert(rd->savfltreguse == 0);
179 /* take arguments out of stack frame */
181 for (p = 0, l = 0; p < md->paramcount; p++) {
182 t = md->paramtypes[p].type;
183 varindex = jd->local_map[l * 5 + t];
186 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
189 if (varindex == UNUSED)
194 s1 = md->params[p].regoff;
195 assert(md->params[p].inmemory); /* all args are on stack */
198 #if defined(ENABLE_SOFTFLOAT)
204 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
205 if (IS_2_WORD_TYPE(t)) {
206 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
208 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
210 } else { /* stack arg -> spilled */
211 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
212 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
213 if (IS_2_WORD_TYPE(t)) {
214 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
215 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
219 #if !defined(ENABLE_SOFTFLOAT)
222 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
223 if (IS_2_WORD_TYPE(t)) {
224 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
226 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
228 } else { /* stack-arg -> spilled */
229 if (IS_2_WORD_TYPE(t)) {
230 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
231 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
233 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
234 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
238 #endif /* SOFTFLOAT */
240 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
241 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
242 } else { /* stack-arg -> spilled */
243 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
244 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
249 } /* end for argument out of stack*/
251 #if defined(ENABLE_THREADS)
252 /* call lock_monitor_enter function */
253 if (checksync && code_is_synchronized(code)) {
254 if (m->flags & ACC_STATIC) {
255 M_AMOV_IMM((&m->clazz->object.header), REG_ATMP1);
257 /* for non-static case the first arg is the object */
258 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
261 M_TRAP(TRAP_NullPointerException);
264 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
265 M_AST(REG_ATMP1, REG_SP, 0 * 4);
266 M_JSR_IMM(LOCK_monitor_enter);
272 /* create replacement points */
273 REPLACEMENT_POINTS_INIT(cd, jd);
275 /* foreach basic block */
276 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
278 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
280 if (bptr->flags >= BBREACHED) {
282 /* branch resolving */
283 codegen_resolve_branchrefs(cd, bptr);
285 /* handle replacement points */
286 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
288 #if defined(ENABLE_PROFILING)
291 /* FIXME there are still some constrcuts to copy in here */
293 #if defined(ENABLE_LSRA)
297 /* copy interface registers to their destination */
303 var = VAR(bptr->invars[len]);
304 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
305 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
306 M_ADRMOVE(REG_ATMP1_XPTR, d);
307 emit_store(jd, NULL, var, d);
310 assert((var->flags & INOUT));
314 /* walk through all instructions */
318 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
319 if (iptr->line != currentline) {
320 linenumbertable_list_entry_add(cd, iptr->line);
321 currentline = iptr->line;
324 MCODECHECK(1024); /* 1kB should be enough */
327 case ICMD_NOP: /* ... ==> ... */
328 case ICMD_POP: /* ..., value ==> ... */
329 case ICMD_POP2: /* ..., value, value ==> ... */
332 case ICMD_INLINE_START:
334 REPLACEMENT_POINT_INLINE_START(cd, iptr);
337 case ICMD_INLINE_BODY:
339 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
340 linenumbertable_list_entry_add_intern(cd, iptr);
341 linenumbertable_list_entry_add(cd, iptr->line);
344 case ICMD_INLINE_END:
346 linenumbertable_list_entry_add_inline(cd, iptr);
347 linenumbertable_list_entry_add(cd, iptr->line);
350 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
353 assert(VAROP(iptr->s1)->type == TYPE_ADR);
354 emit_nullpointer_check(cd, iptr, s1);
358 /* CONST **************************************************************/
359 case ICMD_ICONST: /* ... ==> ..., constant */
360 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
361 M_IMOV_IMM(iptr->sx.val.i, d);
362 emit_store_dst(jd, iptr, d);
365 case ICMD_LCONST: /* ... ==> ..., constant */
367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
368 LCONST(iptr->sx.val.l, d);
369 emit_store_dst(jd, iptr, d);
372 case ICMD_FCONST: /* ... ==> ..., constant */
374 #if defined(ENABLE_SOFTFLOAT)
375 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
376 M_IMOV_IMM(iptr->sx.val.i, d);
377 emit_store_dst(jd, iptr, d);
379 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
380 FCONST(iptr->sx.val.i, d);
381 emit_store_dst(jd, iptr, d);
385 case ICMD_DCONST: /* ... ==> ..., constant */
387 #if defined(ENABLE_SOFTFLOAT)
388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
389 LCONST(iptr->sx.val.l, d);
390 emit_store_dst(jd, iptr, d);
392 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
393 disp = dseg_add_double(cd, iptr->sx.val.d);
394 M_AMOV_IMM(0, REG_ATMP1);
396 M_DLD(d, REG_ATMP1, disp);
397 emit_store_dst(jd, iptr, d);
402 /* some long operations *********************************************/
403 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
404 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
405 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
406 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
407 M_INTMOVE(s2, REG_ITMP1);
408 M_IADD(s1, REG_ITMP1); /* low word */
409 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
410 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
411 M_INTMOVE(s2, REG_ITMP2);
412 M_IADDX(s1, REG_ITMP2); /* high word */
413 emit_store_dst(jd, iptr, d);
416 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
417 /* sx.val.l = constant */
418 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
419 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
420 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
422 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
424 s3 = iptr->sx.val.l & 0xffffffff;
425 M_INTMOVE(s1, REG_ITMP1);
426 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
428 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
429 M_LNGMOVE(REG_ITMP12_PACKED, d);
430 emit_store_dst(jd, iptr, d);
433 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
434 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
435 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
436 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
437 M_INTMOVE(s1, REG_ITMP1);
438 M_ISUB(s2, REG_ITMP1); /* low word */
439 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
440 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
441 M_INTMOVE(s1, REG_ITMP2);
442 M_ISUBX(s2, REG_ITMP2); /* high word */
443 emit_store_dst(jd, iptr, d);
446 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
447 /* sx.val.l = constant */
448 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
449 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
450 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
452 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
454 s3 = (-iptr->sx.val.l) & 0xffffffff;
455 M_INTMOVE(s1, REG_ITMP1);
456 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
458 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
459 M_LNGMOVE(REG_ITMP12_PACKED, d);
460 emit_store_dst(jd, iptr, d);
463 case ICMD_LNEG: /* ..., value ==> ..., - value */
464 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
465 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
466 M_LNGMOVE(s1, REG_ITMP12_PACKED);
467 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
468 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
469 M_LNGMOVE(REG_ITMP12_PACKED, d);
470 emit_store_dst(jd, iptr, d);
473 /* integer operations ************************************************/
474 case ICMD_INEG: /* ..., value ==> ..., - value */
476 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
477 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
478 M_INTMOVE(s1, REG_ITMP1);
480 M_INTMOVE(REG_ITMP1, d);
481 emit_store_dst(jd, iptr, d);
484 case ICMD_I2L: /* ..., value ==> ..., value */
486 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
487 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
488 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
490 M_ISET(GET_HIGH_REG(d));
492 M_ICLR(GET_HIGH_REG(d));
494 emit_store_dst(jd, iptr, d);
497 case ICMD_L2I: /* ..., value ==> ..., value */
499 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
502 emit_store_dst(jd, iptr, d);
504 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
506 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
509 emit_store_dst(jd, iptr, d);
512 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
517 emit_store_dst(jd, iptr, d);
520 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
525 emit_store_dst(jd, iptr, d);
530 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
535 M_INTMOVE(s2, REG_ITMP2);
536 M_IADD(s1, REG_ITMP2);
537 M_INTMOVE(REG_ITMP2, d);
538 emit_store_dst(jd, iptr, d);
541 /* s1.localindex = variable, sx.val.i = constant*/
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
548 M_INTMOVE(s1, REG_ITMP1);
549 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
550 M_INTMOVE(REG_ITMP1, d);
551 emit_store_dst(jd, iptr, d);
554 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
557 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
559 M_INTMOVE(s1, REG_ITMP1);
560 M_ISUB(s2, REG_ITMP1);
561 M_INTMOVE(REG_ITMP1, d);
562 emit_store_dst(jd, iptr, d);
565 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
566 /* sx.val.i = constant */
568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
569 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
570 M_INTMOVE(s1, REG_ITMP1);
571 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
572 M_INTMOVE(REG_ITMP1, d);
573 emit_store_dst(jd, iptr, d);
576 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
580 emit_arithmetic_check(cd, iptr, s2);
581 M_INTMOVE(s1, REG_ITMP1);
582 M_IDIV(s2, REG_ITMP1);
583 M_INTMOVE(REG_ITMP1, d);
584 emit_store_dst(jd, iptr, d);
587 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
590 M_INTMOVE(s1, REG_ITMP1);
594 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
596 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
597 M_ISSR(REG_ITMP2, REG_ITMP1);
598 M_INTMOVE(REG_ITMP1, d);
599 emit_store_dst(jd, iptr, d);
602 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
606 emit_arithmetic_check(cd, iptr, s2);
608 M_ICMP_IMM(0x80000000, s1);
613 M_TPFL; /* hides the next instruction */
614 M_IREM(s2, s1, REG_ITMP3);
616 M_INTMOVE(REG_ITMP3, d);
618 emit_store_dst(jd, iptr, d);
621 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625 M_IMOV(s1, REG_ITMP1);
629 M_IAND_IMM(iptr->sx.val.i, d);
631 M_BGE(2 + 2 + 6 + 2);
632 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
634 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
637 emit_store_dst(jd, iptr, d);
641 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
642 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
644 bte = iptr->sx.s23.s3.bte;
647 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
648 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
649 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
650 /* XXX could be optimized */
651 emit_arithmetic_check(cd, iptr, REG_ITMP3);
653 M_LST(s2, REG_SP, 2 * 4);
654 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
655 M_LST(s1, REG_SP, 0 * 4);
659 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
660 M_LNGMOVE(REG_RESULT_PACKED, d);
661 emit_store_dst(jd, iptr, d);
664 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
667 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
669 M_INTMOVE(s2, REG_ITMP2);
670 M_IMUL(s1, REG_ITMP2);
671 M_INTMOVE(REG_ITMP2, d);
672 emit_store_dst(jd, iptr, d);
675 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
676 /* sx.val.i = constant */
677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
679 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
680 M_IMUL(s1, REG_ITMP2);
681 M_INTMOVE(REG_ITMP2, d);
682 emit_store_dst(jd, iptr, d);
685 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
688 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
689 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
690 M_INTMOVE(s1, REG_ITMP1);
691 M_INTMOVE(s2, REG_ITMP2);
692 M_IAND_IMM(0x1f, REG_ITMP2);
693 M_ISSL(REG_ITMP2, REG_ITMP1);
694 M_INTMOVE(REG_ITMP1, d);
695 emit_store_dst(jd, iptr, d);
698 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
699 /* sx.val.i = constant */
701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
703 if (iptr->sx.val.i & 0x1f) {
704 M_INTMOVE(s1, REG_ITMP1)
705 if ((iptr->sx.val.i & 0x1f) <= 7) {
706 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
708 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
709 M_ISSL(REG_ITMP2, REG_ITMP1);
711 M_INTMOVE(REG_ITMP1, d);
715 emit_store_dst(jd, iptr, d);
718 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
722 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
723 M_INTMOVE(s1, REG_ITMP1);
724 M_INTMOVE(s2, REG_ITMP2);
725 M_IAND_IMM(0x1f, REG_ITMP2);
726 M_ISSR(REG_ITMP2, REG_ITMP1);
727 M_INTMOVE(REG_ITMP1, d);
728 emit_store_dst(jd, iptr, d);
731 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
732 /* sx.val.i = constant */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
736 if (iptr->sx.val.i & 0x1f) {
737 M_INTMOVE(s1, REG_ITMP1)
738 if ((iptr->sx.val.i & 0x1f) <= 7) {
739 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
741 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
742 M_ISSR(REG_ITMP2, REG_ITMP1);
744 M_INTMOVE(REG_ITMP1, d);
748 emit_store_dst(jd, iptr, d);
751 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
756 M_INTMOVE(s1, REG_ITMP1);
757 M_INTMOVE(s2, REG_ITMP2);
758 M_IAND_IMM(0x1f, REG_ITMP2);
759 M_IUSR(REG_ITMP2, REG_ITMP1);
760 M_INTMOVE(REG_ITMP1, d);
761 emit_store_dst(jd, iptr, d);
764 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
765 /* sx.val.i = constant */
766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
768 if (iptr->sx.val.i & 0x1f) {
769 M_INTMOVE(s1, REG_ITMP1)
770 if ((iptr->sx.val.i & 0x1f) <= 7) {
771 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
773 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
774 M_IUSR(REG_ITMP2, REG_ITMP1);
776 M_INTMOVE(REG_ITMP1, d);
780 emit_store_dst(jd, iptr, d);
783 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
786 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
787 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
788 M_INTMOVE(s2, REG_ITMP2);
789 M_IAND(s1, REG_ITMP2);
790 M_INTMOVE(REG_ITMP2, d);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
795 /* sx.val.i = constant */
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
799 M_INTMOVE(s1, REG_ITMP1);
800 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
801 M_INTMOVE(REG_ITMP1, d);
802 emit_store_dst(jd, iptr, d);
805 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809 M_INTMOVE(s2, REG_ITMP2);
810 M_IOR(s1, REG_ITMP2);
811 M_INTMOVE(REG_ITMP2, d);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
816 /* sx.val.i = constant */
817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
819 M_INTMOVE(s1, REG_ITMP1);
820 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
821 M_INTMOVE(REG_ITMP1, d);
822 emit_store_dst(jd, iptr, d);
825 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
829 M_INTMOVE(s2, REG_ITMP2);
830 M_IXOR(s1, REG_ITMP2);
831 M_INTMOVE(REG_ITMP2, d);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
836 /* sx.val.i = constant */
837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
838 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
839 M_INTMOVE(s1, REG_ITMP1);
840 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
841 M_INTMOVE(REG_ITMP1, d);
842 emit_store_dst(jd, iptr, d);
845 /* floating point operations ******************************************/
846 #if !defined(ENABLE_SOFTFLOAT)
847 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
849 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
850 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
854 M_BFUN(14); /* result is -1, branch to end */
855 M_BFLT(10); /* result is -1, branch to end */
857 M_BFEQ(4) /* result is 0, branch to end */
859 emit_store_dst(jd, iptr, d);
862 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg 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_ITMP1);
869 M_BFUN(16); /* result is +1, branch to end */
870 M_BFGT(14); /* result is +1, branch to end */
872 M_BFEQ(8) /* result is 0, branch to end */
874 emit_store_dst(jd, iptr, d);
877 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
878 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
879 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
880 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
881 M_FLTMOVE(s2, REG_FTMP2);
882 M_FMUL(s1, REG_FTMP2);
883 M_FLTMOVE(REG_FTMP2, d);
884 emit_store_dst(jd, iptr, d);
887 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
888 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
889 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
890 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
891 M_DBLMOVE(s2, REG_FTMP2);
892 M_DMUL(s1, REG_FTMP2);
893 M_DBLMOVE(REG_FTMP2, d);
894 emit_store_dst(jd, iptr, d);
897 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
898 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
899 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
900 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
901 M_FLTMOVE(s1, REG_FTMP1);
902 M_FDIV(s2, REG_FTMP1);
903 M_FLTMOVE(REG_FTMP1, d);
904 emit_store_dst(jd, iptr, d);
907 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
908 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
909 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
910 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
911 M_DBLMOVE(s1, REG_FTMP1);
912 M_DDIV(s2, REG_FTMP1);
913 M_DBLMOVE(REG_FTMP1, d);
914 emit_store_dst(jd, iptr, d);
917 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
918 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
919 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
920 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
921 M_FLTMOVE(s2, REG_FTMP2);
922 M_FADD(s1, REG_FTMP2);
923 M_FLTMOVE(REG_FTMP2, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
928 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
929 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
930 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
931 M_DBLMOVE(s2, REG_FTMP2);
932 M_DADD(s1, REG_FTMP2);
933 M_DBLMOVE(REG_FTMP2, d);
934 emit_store_dst(jd, iptr, d);
937 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
938 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
939 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
940 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
941 M_FLTMOVE(s1, REG_FTMP1);
942 M_FSUB(s2, REG_FTMP1);
943 M_FLTMOVE(REG_FTMP1, d);
944 emit_store_dst(jd, iptr, d);
947 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
948 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
949 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
950 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
951 M_DBLMOVE(s1, REG_FTMP1);
952 M_DSUB(s2, REG_FTMP1);
953 M_DBLMOVE(REG_FTMP1, d);
954 emit_store_dst(jd, iptr, d);
957 case ICMD_F2D: /* ..., value ==> ..., (double) value */
958 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
959 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
961 emit_store_dst(jd, iptr, d);
964 case ICMD_D2F: /* ..., value ==> ..., (float) value */
965 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
966 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
968 emit_store_dst(jd, iptr, d);
971 case ICMD_FNEG: /* ..., value ==> ..., - value */
972 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
973 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
975 emit_store_dst(jd, iptr, d);
978 case ICMD_DNEG: /* ..., value ==> ..., - value */
979 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
980 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
982 emit_store_dst(jd, iptr, d);
987 /* load/store/copy/move operations ************************************/
989 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
990 case ICMD_ALOAD: /* s1 = local variable */
994 case ICMD_ISTORE: /* ..., value ==> ... */
1001 emit_copy(jd, iptr);
1006 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1007 emit_copy(jd, iptr);
1011 case ICMD_ACONST: /* ... ==> ..., constant */
1012 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1014 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1015 constant_classref *cr = iptr->sx.val.c.ref;;
1016 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1019 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1021 emit_store_dst(jd, iptr, d);
1023 /* BRANCH *************************************************************/
1025 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1027 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1028 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1030 #ifdef ENABLE_VERIFIER
1031 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1032 unresolved_class *uc = iptr->sx.s23.s2.uc;
1034 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1036 #endif /* ENABLE_VERIFIER */
1037 M_JSR_PCREL(2); /* get current PC */
1040 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1045 case ICMD_GOTO: /* ... ==> ... */
1046 case ICMD_RET: /* ... ==> ... */
1048 emit_br(cd, iptr->dst.block);
1052 case ICMD_JSR: /* ... ==> ... */
1054 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1060 case ICMD_IFNULL: /* ..., value ==> ... */
1061 case ICMD_IFNONNULL:
1062 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1063 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1065 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1073 case ICMD_IFEQ: /* ..., value ==> ... */
1075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076 assert (VAROP(iptr->s1)->type == TYPE_INT);
1077 M_ICMP_IMM(iptr->sx.val.i, s1);
1078 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1081 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1082 case ICMD_IF_ICMPNE:
1083 case ICMD_IF_ICMPLT:
1084 case ICMD_IF_ICMPGT:
1085 case ICMD_IF_ICMPLE:
1086 case ICMD_IF_ICMPGE:
1088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1089 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1091 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1094 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1095 case ICMD_IF_ACMPNE:
1097 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1098 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1100 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1104 /* MEMORY *************************************************************/
1106 case ICMD_GETSTATIC: /* ... ==> ..., value */
1108 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1109 uf = iptr->sx.s23.s3.uf;
1110 fieldtype = uf->fieldref->parseddesc.fd->type;
1113 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1116 fi = iptr->sx.s23.s3.fmiref->p.field;
1117 fieldtype = fi->type;
1118 disp = (intptr_t) fi->value;
1120 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1121 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1126 M_AMOV_IMM(disp, REG_ATMP1);
1127 switch (fieldtype) {
1128 #if defined(ENABLE_SOFTFLOAT)
1132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1133 M_ILD(d, REG_ATMP1, 0);
1136 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1137 M_ALD(d, REG_ATMP1, 0);
1139 #if defined(ENABLE_SOFTFLOAT)
1143 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1144 M_LLD(d, REG_ATMP1, 0);
1146 #if !defined(ENABLE_SOFTFLOAT)
1148 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1149 M_FLD(d, REG_ATMP1, 0);
1152 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1153 M_DLD(d, REG_ATMP1, 0);
1157 emit_store_dst(jd, iptr, d);
1160 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1162 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1163 uf = iptr->sx.s23.s3.uf;
1164 fieldtype = uf->fieldref->parseddesc.fd->type;
1167 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1170 fi = iptr->sx.s23.s3.fmiref->p.field;
1171 fieldtype = fi->type;
1172 disp = (intptr_t) fi->value;
1174 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1175 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1179 M_AMOV_IMM(disp, REG_ATMP1);
1180 switch (fieldtype) {
1181 #if defined(ENABLE_SOFTFLOAT)
1185 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1186 M_IST(s1, REG_ATMP1, 0);
1188 #if defined(ENABLE_SOFTFLOAT)
1192 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1193 M_LST(s1, REG_ATMP1, 0);
1196 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1197 M_AST(s1, REG_ATMP1, 0);
1199 #if !defined(ENABLE_SOFTFLOAT)
1201 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1202 M_FST(s1, REG_ATMP1, 0);
1205 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1206 M_DST(s1, REG_ATMP1, 0);
1213 case ICMD_GETFIELD: /* ... ==> ..., value */
1215 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1217 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1218 uf = iptr->sx.s23.s3.uf;
1219 fieldtype = uf->fieldref->parseddesc.fd->type;
1222 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1225 fi = iptr->sx.s23.s3.fmiref->p.field;
1226 fieldtype = fi->type;
1230 /* implicit null-pointer check */
1231 switch (fieldtype) {
1232 #if defined(ENABLE_SOFTFLOAT)
1236 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1239 #if defined(ENABLE_SOFTFLOAT)
1243 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1247 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1250 #if !defined(ENABLE_SOFTFLOAT)
1252 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1256 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1261 emit_store_dst(jd, iptr, d);
1264 case ICMD_PUTFIELD: /* ..., value ==> ... */
1266 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1268 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1269 uf = iptr->sx.s23.s3.uf;
1270 fieldtype = uf->fieldref->parseddesc.fd->type;
1274 fi = iptr->sx.s23.s3.fmiref->p.field;
1275 fieldtype = fi->type;
1279 if (IS_INT_LNG_TYPE(fieldtype)) {
1280 if (IS_2_WORD_TYPE(fieldtype)) {
1281 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1283 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1286 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1289 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1290 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1292 /* implicit null-pointer check */
1293 switch (fieldtype) {
1294 #if defined(ENABLE_SOFTFLOAT)
1298 M_IST(s2, s1, disp);
1301 #if defined(ENABLE_SOFTFLOAT)
1305 M_LST(s2, s1, disp);
1308 M_AST(s2, s1, disp);
1310 #if !defined(ENABLE_SOFTFLOAT)
1312 M_FST(s2, s1, disp);
1315 M_DST(s2, s1, disp);
1321 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1323 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1324 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1325 /* implicit null-pointer check */
1326 M_ILD(d, s1, OFFSET(java_array_t, size));
1327 emit_store_dst(jd, iptr, d);
1330 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1332 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1333 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1334 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1335 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1336 M_INTMOVE(s2, REG_ITMP2);
1337 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1338 M_ADRMOVE(s1, REG_ATMP1);
1339 M_AADDINT(REG_ITMP2, REG_ATMP1);
1340 /* implicit null-pointer check */
1341 M_LBZX(REG_ATMP1, d);
1343 emit_store_dst(jd, iptr, d);
1346 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1348 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1349 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1351 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1352 M_INTMOVE(s2, REG_ITMP2);
1353 M_ISSL_IMM(1, REG_ITMP2);
1354 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1355 M_ADRMOVE(s1, REG_ATMP1);
1356 M_AADDINT(REG_ITMP2, REG_ATMP1);
1357 /* implicit null-pointer check */
1358 M_LHZX(REG_ATMP1, d);
1360 emit_store_dst(jd, iptr, d);
1363 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1365 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1366 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1369 M_INTMOVE(s2, REG_ITMP2);
1370 M_ISSL_IMM(1, REG_ITMP2);
1371 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1372 M_ADRMOVE(s1, REG_ATMP1);
1373 M_AADDINT(REG_ITMP2, REG_ATMP1);
1375 /* implicit null-pointer check */
1376 M_LHZX(REG_ATMP1, d);
1378 emit_store_dst(jd, iptr, d);
1381 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1383 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1384 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1386 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1387 M_INTMOVE(s2, REG_ITMP2);
1388 M_ISSL_IMM(2, REG_ITMP2);
1389 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1390 M_ADRMOVE(s1, REG_ATMP1);
1391 M_AADDINT(REG_ITMP2, REG_ATMP1);
1392 /* implicit null-pointer check */
1393 M_LWZX(REG_ATMP1, d);
1394 emit_store_dst(jd, iptr, d);
1397 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1398 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1399 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1400 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1401 /* implicit null-pointer check */
1402 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1403 M_INTMOVE(s2, REG_ITMP1);
1404 M_ISSL_IMM(3, REG_ITMP1);
1405 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1406 M_ADRMOVE(s1, REG_ATMP1);
1407 M_AADDINT(REG_ITMP1, REG_ATMP1);
1408 /* implicit null-pointer check */
1409 M_LLD(d, REG_ATMP1, 0);
1410 emit_store_dst(jd, iptr, d);
1413 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1414 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1415 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1416 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1417 M_INTMOVE(s2, REG_ITMP2);
1418 M_ISSL_IMM(2, REG_ITMP2);
1419 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1420 M_ADRMOVE(s1, REG_ATMP1);
1421 M_AADDINT(REG_ITMP2, REG_ATMP1);
1422 /* implicit null-pointer check */
1423 #if !defined(ENABLE_SOFTFLOAT)
1424 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1425 M_FLD(d, REG_ATMP1, 0);
1427 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1428 M_LWZX(REG_ATMP1, d);
1430 emit_store_dst(jd, iptr, d);
1433 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1434 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1435 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1436 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1437 M_INTMOVE(s2, REG_ITMP2);
1438 M_ISSL_IMM(3, REG_ITMP2);
1439 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1440 M_ADRMOVE(s1, REG_ATMP1);
1441 M_AADDINT(REG_ITMP2, REG_ATMP1);
1442 /* implicit null-pointer check */
1443 #if !defined(ENABLE_SOFTFLOAT)
1444 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1445 M_DLD(d, REG_ATMP1, 0);
1447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1448 M_LLD(d, REG_ATMP1, 0);
1450 emit_store_dst(jd, iptr, d);
1453 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1454 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1455 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1456 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1457 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1458 M_INTMOVE(s2, REG_ITMP2);
1459 M_ISSL_IMM(2, REG_ITMP2);
1460 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1461 M_ADRMOVE(s1, REG_ATMP1);
1462 M_AADDINT(REG_ITMP2, REG_ATMP1);
1464 /* implicit null-pointer check */
1465 M_LAX(REG_ATMP1, d);
1466 emit_store_dst(jd, iptr, d);
1470 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1471 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1472 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1473 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1474 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1475 M_INTMOVE(s2, REG_ITMP2);
1476 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1477 M_ADRMOVE(s1, REG_ATMP1);
1478 M_AADDINT(REG_ITMP2, REG_ATMP1);
1479 /* implicit null-pointer check */
1480 M_STBX(REG_ATMP1, s3);
1483 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1487 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1488 M_INTMOVE(s2, REG_ITMP2);
1489 M_ISSL_IMM(1, REG_ITMP2);
1490 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1491 M_ADRMOVE(s1, REG_ATMP1);
1492 M_AADDINT(REG_ITMP2, REG_ATMP1);
1493 /* implicit null-pointer check */
1494 M_STHX(REG_ATMP1, s3);
1497 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1499 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1500 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1502 M_INTMOVE(s2, REG_ITMP2);
1503 M_ISSL_IMM(1, REG_ITMP2);
1504 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1505 M_ADRMOVE(s1, REG_ATMP1);
1506 M_AADDINT(REG_ITMP2, REG_ATMP1);
1507 /* implicit null-pointer check */
1508 M_STHX(REG_ATMP1, s3);
1511 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1513 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1514 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1515 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1516 M_INTMOVE(s2, REG_ITMP2);
1517 M_ISSL_IMM(2, REG_ITMP2);
1518 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1519 M_ADRMOVE(s1, REG_ATMP1);
1520 M_AADDINT(REG_ITMP2, REG_ATMP1);
1521 /* implicit null-pointer check */
1522 M_STWX(REG_ATMP1, s3);
1525 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1526 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1527 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1528 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1530 M_INTMOVE(s2, REG_ITMP1);
1531 M_ISSL_IMM(3, REG_ITMP1);
1532 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1533 M_ADRMOVE(s1, REG_ATMP1);
1534 M_AADDINT(REG_ITMP1, REG_ATMP1);
1535 /* implicit null-pointer check */
1536 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1537 M_LST(s3, REG_ATMP1, 0);
1540 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1544 M_INTMOVE(s2, REG_ITMP2);
1545 M_ISSL_IMM(2, REG_ITMP2);
1546 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1547 M_ADRMOVE(s1, REG_ATMP1);
1548 M_AADDINT(REG_ITMP2, REG_ATMP1);
1549 /* implicit null-pointer check */
1550 #if !defined(ENABLE_SOFTFLOAT)
1551 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1552 M_FST(s3, REG_ATMP1, 0);
1554 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1555 M_STWX(REG_ATMP1, s3);
1559 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1561 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1562 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1563 M_INTMOVE(s2, REG_ITMP2);
1564 M_ISSL_IMM(3, REG_ITMP2);
1565 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1566 M_ADRMOVE(s1, REG_ATMP1);
1567 M_AADDINT(REG_ITMP2, REG_ATMP1);
1568 /* implicit null-pointer check */
1569 #if !defined(ENABLE_SOFTFLOAT)
1570 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1571 M_DST(s3, REG_ATMP1, 0);
1573 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1574 /* implicit null-pointer check */
1575 M_LST(s3, REG_ATMP1, 0);
1579 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1581 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1582 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1583 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1584 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1586 /* XXX what if array is NULL */
1587 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1589 M_AST(s1, REG_SP, 0*4);
1590 M_AST(s3, REG_SP, 1*4);
1591 M_JSR_IMM(BUILTIN_FAST_canstore);
1592 emit_arraystore_check(cd, iptr);
1594 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1595 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1596 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1597 M_INTMOVE(s2, REG_ITMP1);
1598 M_ISSL_IMM(2, REG_ITMP1);
1599 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1600 M_ADRMOVE(s1, REG_ATMP1);
1601 M_AADDINT(REG_ITMP1, REG_ATMP1);
1602 /* implicit null-pointer check */
1603 M_STAX(REG_ATMP1, s3);
1608 /* METHOD INVOCATION *********************************************************/
1609 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1610 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1612 bte = iptr->sx.s23.s3.bte;
1616 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1617 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1618 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1619 case ICMD_INVOKEINTERFACE:
1620 REPLACEMENT_POINT_INVOKE(cd, iptr);
1622 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1624 um = iptr->sx.s23.s3.um;
1625 md = um->methodref->parseddesc.md;
1628 lm = iptr->sx.s23.s3.fmiref->p.method;
1630 md = lm->parseddesc;
1633 s3 = md->paramcount;
1635 MCODECHECK((s3 << 1) + 64);
1637 /* copy arguments to stack */
1638 for (s3 = s3 - 1; s3 >= 0; s3--) {
1639 var = VAR(iptr->sx.s23.s2.args[s3]);
1640 /* already preallocated */
1641 if (var->flags & PREALLOC) continue;
1643 if (!md->params[s3].inmemory) assert(0);
1645 switch (var->type) {
1646 #if defined(ENABLE_SOFTFLOAT)
1650 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1651 M_LST(d, REG_SP, md->params[s3].regoff);
1653 #if defined(ENABLE_SOFTFLOAT)
1657 d = emit_load(jd, iptr, var, REG_ITMP1);
1658 M_IST(d, REG_SP, md->params[s3].regoff);
1661 d = emit_load(jd, iptr, var, REG_ATMP1);
1662 M_AST(d, REG_SP, md->params[s3].regoff);
1664 #if !defined(ENABLE_SOFTFLOAT)
1666 d = emit_load(jd, iptr, var, REG_FTMP1);
1667 M_FST(d, REG_SP, md->params[s3].regoff);
1670 d = emit_load(jd, iptr, var, REG_FTMP1);
1671 M_DST(d, REG_SP, md->params[s3].regoff);
1679 /* arguments in place now */
1682 if (bte->stub == NULL)
1683 disp = (ptrint) bte->fp;
1685 disp = (ptrint) bte->stub;
1686 d = md->returntype.type;
1689 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1692 case ICMD_INVOKESPECIAL:
1693 /* adress register for sure */
1694 M_ALD(REG_ATMP1, REG_SP, 0);
1695 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1697 case ICMD_INVOKESTATIC:
1699 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1701 M_AMOV_IMM(disp, REG_ATMP1);
1703 disp = lm->stubroutine;
1704 M_AMOV_IMM(disp, REG_ATMP1);
1707 /* generate the actual call */
1709 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1713 case ICMD_INVOKEVIRTUAL:
1715 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1718 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1720 /* load object pointer (==argument 0) */
1721 M_ALD(REG_ATMP1, REG_SP, 0);
1722 /* implicit null-pointer check */
1723 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1724 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1725 /* generate the actual call */
1728 case ICMD_INVOKEINTERFACE:
1730 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1735 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
1736 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1738 /* load object pointer (==argument 0) */
1739 M_ALD(REG_ATMP1, REG_SP, 0);
1741 /* implicit null-pointer check */
1742 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1743 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1744 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1746 /* generate the actual call */
1748 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1752 } /* switch (iptr->opc) */
1754 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1755 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1757 /* store return value */
1758 d = md->returntype.type;
1761 case TYPE_VOID: break;
1762 #if defined(ENABLE_SOFTFLOAT)
1766 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1767 M_INTMOVE(REG_RESULT, s1);
1769 #if defined(ENABLE_SOFTFLOAT)
1773 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1774 M_LNGMOVE(REG_RESULT_PACKED, s1);
1777 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1778 /* all stuff is returned in %d0 */
1779 M_INT2ADRMOVE(REG_RESULT, s1);
1781 #if !defined(ENABLE_SOFTFLOAT)
1783 * for BUILTINS float values are returned in %d0,%d1
1784 * within cacao we use %fp0 for that.
1787 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1788 if (iptr->opc == ICMD_BUILTIN) {
1789 M_INT2FLTMOVE(REG_FRESULT, s1);
1791 M_FLTMOVE(REG_FRESULT, s1);
1795 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1796 if (iptr->opc == ICMD_BUILTIN) {
1797 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1798 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1800 M_DBLMOVE(REG_FRESULT, s1);
1807 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1808 break; /* ICMD_INVOKE* */
1810 #if defined(ENABLE_SOFTFLOAT)
1813 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1815 REPLACEMENT_POINT_RETURN(cd, iptr);
1816 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1817 M_INTMOVE(s1, REG_RESULT);
1818 goto nowperformreturn;
1820 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1822 REPLACEMENT_POINT_RETURN(cd, iptr);
1823 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1824 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1825 M_ADR2INTMOVE(s1, REG_RESULT);
1827 #ifdef ENABLE_VERIFIER
1828 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1829 unresolved_class *uc = iptr->sx.s23.s2.uc;
1831 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1833 #endif /* ENABLE_VERIFIER */
1834 goto nowperformreturn;
1836 #if defined(ENABLE_SOFTFLOAT)
1839 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1840 REPLACEMENT_POINT_RETURN(cd, iptr);
1841 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1842 M_LNGMOVE(s1, REG_RESULT_PACKED);
1843 goto nowperformreturn;
1845 #if !defined(ENABLE_SOFTFLOAT)
1846 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1847 REPLACEMENT_POINT_RETURN(cd, iptr);
1848 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1849 M_FLTMOVE(s1, REG_FRESULT);
1850 goto nowperformreturn;
1853 REPLACEMENT_POINT_RETURN(cd, iptr);
1854 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1855 M_DBLMOVE(s1, REG_FRESULT);
1856 goto nowperformreturn;
1860 case ICMD_RETURN: /* ... ==> ... */
1862 REPLACEMENT_POINT_RETURN(cd, iptr);
1868 p = cd->stackframesize;
1870 /* call trace function */
1871 #if !defined(NDEBUG)
1872 emit_verbosecall_exit(jd);
1875 #if defined(ENABLE_THREADS)
1876 /* call lock_monitor_exit */
1877 if (checksync && code_is_synchronized(code)) {
1878 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1880 /* we need to save the proper return value */
1881 /* we do not care for the long -> doubel convert space here */
1882 switch (iptr->opc) {
1883 #if defined(ENABLE_SOFTFLOAT)
1887 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1889 #if defined(ENABLE_SOFTFLOAT)
1894 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1896 #if !defined(ENABLE_SOFTFLOAT)
1898 M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1901 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1906 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1907 M_JSR_IMM(LOCK_monitor_exit);
1909 /* and now restore the proper return value */
1910 switch (iptr->opc) {
1912 #if defined(ENABLE_SOFTFLOAT)
1916 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1918 #if defined(ENABLE_SOFTFLOAT)
1923 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1925 #if !defined(ENABLE_SOFTFLOAT)
1927 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1930 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1938 /* restore return address */
1940 if (!code_is_leafmethod(code)) {
1941 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1942 may have a displacement overflow. */
1944 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1948 /* restore saved registers */
1950 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1951 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1953 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1954 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1956 #if !defined(ENABLE_SOFTFLOAT)
1957 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1958 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1961 /* deallocate stack */
1962 M_AADD_IMM(cd->stackframesize, REG_SP);
1968 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1969 /* val.a: (classinfo*) superclass */
1971 /* superclass is an interface:
1973 * return (sub != NULL) &&
1974 * (sub->vftbl->interfacetablelength > super->index) &&
1975 * (sub->vftbl->interfacetable[-super->index] != NULL);
1977 * superclass is a class:
1979 * return ((sub != NULL) && (0
1980 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1981 * super->vftbl->diffvall));
1988 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1993 super = iptr->sx.s23.s3.c.cls;
1994 superindex = super->index;
1997 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1998 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2000 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2001 assert(VAROP(iptr->dst)->type == TYPE_INT);
2005 /* if class is not resolved, check which code to call */
2007 if (super == NULL) {
2009 emit_label_beq(cd, BRANCH_LABEL_1);
2011 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2013 M_IMOV_IMM32(0, REG_ITMP3);
2014 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2015 emit_label_beq(cd, BRANCH_LABEL_2);
2018 /* interface instanceof code */
2020 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2021 if (super == NULL) {
2022 patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2025 emit_label_beq(cd, BRANCH_LABEL_3);
2028 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2029 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2030 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
2033 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
2039 emit_label_br(cd, BRANCH_LABEL_4);
2041 emit_label(cd, BRANCH_LABEL_3);
2044 /* class instanceof code */
2046 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2047 if (super == NULL) {
2048 emit_label(cd, BRANCH_LABEL_2);
2050 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2051 M_AMOV_IMM(0, REG_ATMP2);
2053 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2055 emit_label_beq(cd, BRANCH_LABEL_5);
2058 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2060 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2061 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2062 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2064 M_ISUB(REG_ITMP3, REG_ITMP1);
2065 M_ICMP(REG_ITMP2, REG_ITMP1);
2068 M_TPFW; /* overlaps next instruction */
2072 emit_label(cd, BRANCH_LABEL_5);
2075 if (super == NULL) {
2076 emit_label(cd, BRANCH_LABEL_1);
2077 emit_label(cd, BRANCH_LABEL_4);
2080 emit_store_dst(jd, iptr, d);
2084 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2085 /* val.a: (classinfo*) superclass */
2087 /* superclass is an interface:
2089 * OK if ((sub == NULL) ||
2090 * (sub->vftbl->interfacetablelength > super->index) &&
2091 * (sub->vftbl->interfacetable[-super->index] != NULL));
2093 * superclass is a class:
2095 * OK if ((sub == NULL) || (0
2096 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2097 * super->vftbl->diffvall));
2100 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2101 /* object type cast-check */
2106 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2111 super = iptr->sx.s23.s3.c.cls;
2112 superindex = super->index;
2115 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2116 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2118 /* if class is not resolved, check which code to call */
2120 if (super == NULL) {
2122 emit_label_beq(cd, BRANCH_LABEL_1);
2124 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2126 M_IMOV_IMM32(0, REG_ITMP2);
2127 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2128 emit_label_beq(cd, BRANCH_LABEL_2);
2131 /* interface checkcast code */
2133 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2134 if (super == NULL) {
2135 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2138 emit_label_beq(cd, BRANCH_LABEL_3);
2141 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2142 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2144 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2146 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2148 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2150 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2153 emit_label_br(cd, BRANCH_LABEL_4);
2155 emit_label(cd, BRANCH_LABEL_3);
2158 /* class checkcast code */
2160 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2161 if (super == NULL) {
2162 emit_label(cd, BRANCH_LABEL_2);
2164 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2165 M_AMOV_IMM(0, REG_ATMP3);
2167 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2169 emit_label_beq(cd, BRANCH_LABEL_5);
2172 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2174 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2175 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2176 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2178 M_ISUB(REG_ITMP1, REG_ITMP3);
2179 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2181 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2184 emit_label(cd, BRANCH_LABEL_5);
2187 if (super == NULL) {
2188 emit_label(cd, BRANCH_LABEL_1);
2189 emit_label(cd, BRANCH_LABEL_4);
2192 d = codegen_reg_of_dst(jd, iptr, s1);
2194 /* array type cast-check */
2196 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2198 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2199 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2200 M_AMOV_IMM(0, REG_ATMP1);
2202 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2207 M_JSR_IMM(BUILTIN_arraycheckcast);
2208 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2210 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2213 d = codegen_reg_of_dst(jd, iptr, s1);
2215 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2217 emit_store_dst(jd, iptr, d);
2220 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2223 branch_target_t *table;
2225 table = iptr->dst.table;
2227 l = iptr->sx.s23.s2.tablelow;
2228 i = iptr->sx.s23.s3.tablehigh;
2230 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2231 M_INTMOVE(s1, REG_ITMP1);
2232 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2237 M_ICMP_IMM(i - 1, REG_ITMP1);
2238 emit_bugt(cd, table[0].block);
2240 /* build jump table top down and use address of lowest entry */
2244 dseg_add_target(cd, table->block);
2248 /* length of dataseg after last dseg_add_target is used by load */
2249 M_AMOV_IMM(0, REG_ATMP2);
2252 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2253 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2254 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2255 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2262 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2265 lookup_target_t *lookup;
2267 lookup = iptr->dst.lookup;
2269 i = iptr->sx.s23.s2.lookupcount;
2271 MCODECHECK((i<<2)+8);
2272 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2275 M_ICMP_IMM(lookup->value, s1);
2276 emit_beq(cd, lookup->target.block);
2280 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2285 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2287 /* check for negative sizes and copy sizes to stack if necessary */
2288 MCODECHECK((iptr->s1.argcount << 1) + 64);
2290 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2291 var = VAR(iptr->sx.s23.s2.args[s1]);
2293 /* Already Preallocated? */
2294 if (!(var->flags & PREALLOC)) {
2295 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2296 M_IST(s2, REG_SP, (s1 + 3) * 4);
2300 /* a0 = dimension count */
2301 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2302 M_IST(REG_ITMP1, REG_SP, 0*4);
2304 /* a1 = arraydescriptor */
2305 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2306 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2307 M_AMOV_IMM(0, REG_ATMP1);
2309 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2311 M_AST(REG_ATMP1, REG_SP, 1*4);
2313 /* a2 = pointer to dimensions = stack pointer */
2314 M_AMOV(REG_SP, REG_ATMP1);
2315 M_AADD_IMM(3*4, REG_ATMP1);
2316 M_AST(REG_ATMP1, REG_SP, 2*4);
2318 M_JSR_IMM(BUILTIN_multianewarray);
2320 /* check for exception before result assignment */
2321 emit_exception_check(cd, iptr);
2323 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2324 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2325 M_INT2ADRMOVE(REG_RESULT, d);
2326 emit_store_dst(jd, iptr, d);
2332 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2333 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2336 /* M_TPF; */ /* nop after each ICMD */
2337 } /* for each instruction */
2339 /* At the end of a basic block we may have to append some nops,
2340 because the patcher stub calling code might be longer than the
2341 actual instruction. So codepatching does not change the
2342 following block unintentionally. */
2344 if (cd->mcodeptr < cd->lastmcodeptr) {
2345 while (cd->mcodeptr < cd->lastmcodeptr) {
2351 } /* if (btpre->flags >= BBREACHED) */
2352 } /* for each basic block */
2354 /* generate stubs */
2355 emit_patcher_traps(jd);
2360 /* codegen_emit_stub_native ****************************************************
2362 Emits a stub routine which calls a native method.
2364 *******************************************************************************/
2366 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2375 /* get required compiler data */
2384 /* calc stackframe size */
2385 cd->stackframesize =
2386 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2387 sizeof(localref_table) / SIZEOF_VOID_P +
2389 1 + /* functionptr */
2390 4; /* args for codegen_start_native_call */
2392 /* create method header */
2393 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2394 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2395 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2396 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2397 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2400 M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
2402 /* put arguments for codegen_start_native_call onto stack */
2403 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2405 M_AMOV(REG_SP, REG_ATMP1);
2406 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2408 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2409 dseg_adddata(cd); /* this patches it */
2411 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2413 M_JSR_IMM(codegen_start_native_call);
2415 /* remember class argument */
2416 if (m->flags & ACC_STATIC)
2417 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2419 /* copy arguments into stackframe */
2420 for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) {
2421 t = md->paramtypes[i].type;
2422 /* all arguments via stack */
2423 assert(md->params[i].inmemory);
2425 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
2426 s2 = nmd->params[j].regoff;
2428 /* simply copy argument stack */
2429 M_ILD(REG_ITMP1, REG_SP, s1);
2430 M_IST(REG_ITMP1, REG_SP, s2);
2431 if (IS_2_WORD_TYPE(t)) {
2432 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2433 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2437 /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
2438 if (m->flags & ACC_NATIVE) {
2439 /* for static function class as second arg */
2440 if (m->flags & ACC_STATIC)
2441 M_AST(REG_ATMP3, REG_SP, 1 * 4);
2443 /* env ist first argument */
2444 M_AMOV_IMM(VM_get_jnienv(), REG_ATMP1);
2445 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2448 /* call the native function */
2449 M_AMOV_IMM(f, REG_ATMP2);
2452 /* save return value */
2453 switch (md->returntype.type) {
2454 case TYPE_VOID: break;
2456 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2459 M_IST(REG_D1, REG_SP, 2 * 8);
2465 M_IST(REG_D0, REG_SP, 2 * 8); /* XXX can this be correct ? */
2471 /* remove native stackframe info */
2472 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2474 M_AMOV(REG_SP, REG_ATMP1);
2475 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2477 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2478 dseg_adddata(cd); /* this patches it */
2480 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2482 M_JSR_IMM(codegen_finish_native_call);
2484 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2485 /* restore return value */
2486 switch (md->returntype.type) {
2487 case TYPE_VOID: break;
2490 case TYPE_LNG: M_ILD(REG_D1, REG_SP, 2 * 8);
2495 M_ILD(REG_D0, REG_SP, 2 * 8); /* XXX */
2500 #if !defined(ENABLE_SOFTFLOAT)
2501 /* additionally load values into floating points registers
2502 * as cacao jit code expects them there */
2503 switch (md->returntype.type) {
2505 M_FLD(REG_D0, REG_SP, 2 * 8);
2508 M_DLD(REG_D0, REG_SP, 2 * 8); /* XXX */
2512 /* restore saved registers */
2514 M_AADD_IMM(cd->stackframesize*8, REG_SP);
2515 /* check for exception */
2520 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2522 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2523 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2524 M_JMP_IMM(asm_handle_nat_exception);
2526 /* should never be reached from within jit code*/
2532 * These are local overrides for various environment variables in Emacs.
2533 * Please do not remove this and leave it at the end of the file, where
2534 * Emacs will automagically detect them.
2535 * ---------------------------------------------------------------------
2538 * indent-tabs-mode: t
2542 * vim:noexpandtab:sw=4:ts=4: