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"
39 #include "native/localref.hpp"
40 #include "native/native.hpp"
42 #include "threads/lock.hpp"
44 #include "vm/jit/builtin.hpp"
45 #include "vm/exceptions.hpp"
46 #include "vm/global.h"
47 #include "vm/loader.hpp"
48 #include "vm/options.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.hpp"
54 #include "vm/jit/patcher-common.hpp"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/linenumbertable.hpp"
57 #include "vm/jit/emit-common.hpp"
58 #include "vm/jit/jit.hpp"
59 #include "vm/jit/abi.h"
60 #include "vm/jit/parse.hpp"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.hpp"
63 #include "vm/jit/stacktrace.hpp"
64 #include "vm/jit/trap.h"
67 bool codegen_emit(jitdata *jd)
73 s4 len, s1, s2, s3, d, disp;
78 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
79 unresolved_method *um;
80 builtintable_entry *bte;
87 /* get required compiler data */
94 /* prevent compiler warnings */
102 /* save calle saved registers */
103 s4 savedregs_num = 0;
105 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
106 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
107 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
109 cd->stackframesize = rd->memuse + savedregs_num;
111 /* we always add 2 stack slots.
112 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
113 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
114 * on the other hand we could use 2 words when a builtin returns a doulbe which are
115 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
116 * so we always _need_ at least 2 slots, and this keeps the code simple */
117 cd->stackframesize += 2;
119 cd->stackframesize *= 8; /* we use 8 byte stack slots */
122 #if defined(ENABLE_THREADS)
123 /* we need additional space to save argument of monitor_enter */
124 if (checksync && code_is_synchronized(code)) {
125 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
126 cd->stackframesize += 2;
128 cd->stackframesize += 1;
134 /* create method header */
135 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
136 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
138 code->synchronizedoffset = rd->memuse * 8;
140 /* REMOVEME: We still need it for exception handling in assembler. */
142 if (code_is_leafmethod(code))
143 (void) dseg_add_unique_s4(cd, 1);
145 (void) dseg_add_unique_s4(cd, 0);
147 /* XXX we use the IntSave a split field for the adr now */
148 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
149 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
151 #if defined(ENABLE_PROFILING)
156 emit_verbosecall_enter(jd);
158 /* create stack frame */
159 M_AADD_IMM(-(cd->stackframesize), REG_SP);
161 /* save used callee saved registers */
162 p = cd->stackframesize;
163 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
164 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
166 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
167 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
169 #if !defined(ENABLE_SOFTFLOAT)
170 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
171 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
174 assert(FLT_SAV_CNT == 0);
175 assert(rd->savfltreguse == 0);
177 /* take arguments out of stack frame */
179 for (p = 0, l = 0; p < md->paramcount; p++) {
180 t = md->paramtypes[p].type;
181 varindex = jd->local_map[l * 5 + t];
184 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
187 if (varindex == UNUSED)
192 s1 = md->params[p].regoff;
193 assert(md->params[p].inmemory); /* all args are on stack */
196 #if defined(ENABLE_SOFTFLOAT)
202 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
203 if (IS_2_WORD_TYPE(t)) {
204 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
206 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
208 } else { /* stack arg -> spilled */
209 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
210 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
211 if (IS_2_WORD_TYPE(t)) {
212 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
213 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
217 #if !defined(ENABLE_SOFTFLOAT)
220 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
221 if (IS_2_WORD_TYPE(t)) {
222 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
224 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
226 } else { /* stack-arg -> spilled */
227 if (IS_2_WORD_TYPE(t)) {
228 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
229 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
231 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
232 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
236 #endif /* SOFTFLOAT */
238 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
239 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
240 } else { /* stack-arg -> spilled */
241 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
242 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
247 } /* end for argument out of stack*/
249 #if defined(ENABLE_THREADS)
250 /* call lock_monitor_enter function */
251 if (checksync && code_is_synchronized(code)) {
252 if (m->flags & ACC_STATIC) {
253 M_AMOV_IMM((&m->clazz->object.header), REG_ATMP1);
255 /* for non-static case the first arg is the object */
256 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
259 M_TRAP(TRAP_NullPointerException);
262 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
263 M_AST(REG_ATMP1, REG_SP, 0 * 4);
264 M_JSR_IMM(LOCK_monitor_enter);
270 /* create replacement points */
271 REPLACEMENT_POINTS_INIT(cd, jd);
273 /* foreach basic block */
274 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
276 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
278 if (bptr->flags >= BBREACHED) {
280 /* branch resolving */
281 codegen_resolve_branchrefs(cd, bptr);
283 /* handle replacement points */
284 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
286 #if defined(ENABLE_PROFILING)
289 /* FIXME there are still some constrcuts to copy in here */
291 #if defined(ENABLE_LSRA)
295 /* copy interface registers to their destination */
301 var = VAR(bptr->invars[len]);
302 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
303 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
304 M_ADRMOVE(REG_ATMP1_XPTR, d);
305 emit_store(jd, NULL, var, d);
308 assert((var->flags & INOUT));
312 /* walk through all instructions */
316 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
317 if (iptr->line != currentline) {
318 linenumbertable_list_entry_add(cd, iptr->line);
319 currentline = iptr->line;
322 MCODECHECK(1024); /* 1kB should be enough */
325 case ICMD_NOP: /* ... ==> ... */
326 case ICMD_POP: /* ..., value ==> ... */
327 case ICMD_POP2: /* ..., value, value ==> ... */
330 case ICMD_INLINE_START:
332 REPLACEMENT_POINT_INLINE_START(cd, iptr);
335 case ICMD_INLINE_BODY:
337 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
338 linenumbertable_list_entry_add_intern(cd, iptr);
339 linenumbertable_list_entry_add(cd, iptr->line);
342 case ICMD_INLINE_END:
344 linenumbertable_list_entry_add_inline(cd, iptr);
345 linenumbertable_list_entry_add(cd, iptr->line);
348 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
350 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
351 assert(VAROP(iptr->s1)->type == TYPE_ADR);
352 emit_nullpointer_check(cd, iptr, s1);
356 /* CONST **************************************************************/
357 case ICMD_ICONST: /* ... ==> ..., constant */
358 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
359 M_IMOV_IMM(iptr->sx.val.i, d);
360 emit_store_dst(jd, iptr, d);
363 case ICMD_LCONST: /* ... ==> ..., constant */
365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
366 LCONST(iptr->sx.val.l, d);
367 emit_store_dst(jd, iptr, d);
370 case ICMD_FCONST: /* ... ==> ..., constant */
372 #if defined(ENABLE_SOFTFLOAT)
373 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
374 M_IMOV_IMM(iptr->sx.val.i, d);
375 emit_store_dst(jd, iptr, d);
377 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
378 FCONST(iptr->sx.val.i, d);
379 emit_store_dst(jd, iptr, d);
383 case ICMD_DCONST: /* ... ==> ..., constant */
385 #if defined(ENABLE_SOFTFLOAT)
386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
387 LCONST(iptr->sx.val.l, d);
388 emit_store_dst(jd, iptr, d);
390 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
391 disp = dseg_add_double(cd, iptr->sx.val.d);
392 M_AMOV_IMM(0, REG_ATMP1);
394 M_DLD(d, REG_ATMP1, disp);
395 emit_store_dst(jd, iptr, d);
400 /* some long operations *********************************************/
401 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
402 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
403 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
404 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
405 M_INTMOVE(s2, REG_ITMP1);
406 M_IADD(s1, REG_ITMP1); /* low word */
407 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
408 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
409 M_INTMOVE(s2, REG_ITMP2);
410 M_IADDX(s1, REG_ITMP2); /* high word */
411 emit_store_dst(jd, iptr, d);
414 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
415 /* sx.val.l = constant */
416 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
417 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
418 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
420 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
422 s3 = iptr->sx.val.l & 0xffffffff;
423 M_INTMOVE(s1, REG_ITMP1);
424 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
426 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
427 M_LNGMOVE(REG_ITMP12_PACKED, d);
428 emit_store_dst(jd, iptr, d);
431 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
432 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
433 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
435 M_INTMOVE(s1, REG_ITMP1);
436 M_ISUB(s2, REG_ITMP1); /* low word */
437 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
438 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
439 M_INTMOVE(s1, REG_ITMP2);
440 M_ISUBX(s2, REG_ITMP2); /* high word */
441 emit_store_dst(jd, iptr, d);
444 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
445 /* sx.val.l = constant */
446 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
447 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
448 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
450 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
452 s3 = (-iptr->sx.val.l) & 0xffffffff;
453 M_INTMOVE(s1, REG_ITMP1);
454 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
456 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
457 M_LNGMOVE(REG_ITMP12_PACKED, d);
458 emit_store_dst(jd, iptr, d);
461 case ICMD_LNEG: /* ..., value ==> ..., - value */
462 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
464 M_LNGMOVE(s1, REG_ITMP12_PACKED);
465 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
466 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
467 M_LNGMOVE(REG_ITMP12_PACKED, d);
468 emit_store_dst(jd, iptr, d);
471 /* integer operations ************************************************/
472 case ICMD_INEG: /* ..., value ==> ..., - value */
474 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
475 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
476 M_INTMOVE(s1, REG_ITMP1);
478 M_INTMOVE(REG_ITMP1, d);
479 emit_store_dst(jd, iptr, d);
482 case ICMD_I2L: /* ..., value ==> ..., value */
484 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
486 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
488 M_ISET(GET_HIGH_REG(d));
490 M_ICLR(GET_HIGH_REG(d));
492 emit_store_dst(jd, iptr, d);
495 case ICMD_L2I: /* ..., value ==> ..., value */
497 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
500 emit_store_dst(jd, iptr, d);
502 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
505 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
507 emit_store_dst(jd, iptr, d);
510 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
513 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
515 emit_store_dst(jd, iptr, d);
518 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
523 emit_store_dst(jd, iptr, d);
528 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
531 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
533 M_INTMOVE(s2, REG_ITMP2);
534 M_IADD(s1, REG_ITMP2);
535 M_INTMOVE(REG_ITMP2, d);
536 emit_store_dst(jd, iptr, d);
539 /* s1.localindex = variable, sx.val.i = constant*/
544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
546 M_INTMOVE(s1, REG_ITMP1);
547 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
548 M_INTMOVE(REG_ITMP1, d);
549 emit_store_dst(jd, iptr, d);
552 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
555 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
557 M_INTMOVE(s1, REG_ITMP1);
558 M_ISUB(s2, REG_ITMP1);
559 M_INTMOVE(REG_ITMP1, d);
560 emit_store_dst(jd, iptr, d);
563 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
564 /* sx.val.i = constant */
566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
568 M_INTMOVE(s1, REG_ITMP1);
569 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
570 M_INTMOVE(REG_ITMP1, d);
571 emit_store_dst(jd, iptr, d);
574 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
578 emit_arithmetic_check(cd, iptr, s2);
579 M_INTMOVE(s1, REG_ITMP1);
580 M_IDIV(s2, REG_ITMP1);
581 M_INTMOVE(REG_ITMP1, d);
582 emit_store_dst(jd, iptr, d);
585 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
586 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
587 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
588 M_INTMOVE(s1, REG_ITMP1);
592 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
594 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
595 M_ISSR(REG_ITMP2, REG_ITMP1);
596 M_INTMOVE(REG_ITMP1, d);
597 emit_store_dst(jd, iptr, d);
600 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
602 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
604 emit_arithmetic_check(cd, iptr, s2);
606 M_ICMP_IMM(0x80000000, s1);
611 M_TPFL; /* hides the next instruction */
612 M_IREM(s2, s1, REG_ITMP3);
614 M_INTMOVE(REG_ITMP3, d);
616 emit_store_dst(jd, iptr, d);
619 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
620 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
623 M_IMOV(s1, REG_ITMP1);
627 M_IAND_IMM(iptr->sx.val.i, d);
629 M_BGE(2 + 2 + 6 + 2);
630 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
632 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
635 emit_store_dst(jd, iptr, d);
639 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
640 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
642 bte = iptr->sx.s23.s3.bte;
645 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
646 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
647 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
648 /* XXX could be optimized */
649 emit_arithmetic_check(cd, iptr, REG_ITMP3);
651 M_LST(s2, REG_SP, 2 * 4);
652 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
653 M_LST(s1, REG_SP, 0 * 4);
657 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
658 M_LNGMOVE(REG_RESULT_PACKED, d);
659 emit_store_dst(jd, iptr, d);
662 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
666 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
667 M_INTMOVE(s2, REG_ITMP2);
668 M_IMUL(s1, REG_ITMP2);
669 M_INTMOVE(REG_ITMP2, d);
670 emit_store_dst(jd, iptr, d);
673 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
674 /* sx.val.i = constant */
675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
676 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
678 M_IMUL(s1, REG_ITMP2);
679 M_INTMOVE(REG_ITMP2, d);
680 emit_store_dst(jd, iptr, d);
683 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
688 M_INTMOVE(s1, REG_ITMP1);
689 M_INTMOVE(s2, REG_ITMP2);
690 M_IAND_IMM(0x1f, REG_ITMP2);
691 M_ISSL(REG_ITMP2, REG_ITMP1);
692 M_INTMOVE(REG_ITMP1, d);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
697 /* sx.val.i = constant */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
701 if (iptr->sx.val.i & 0x1f) {
702 M_INTMOVE(s1, REG_ITMP1)
703 if ((iptr->sx.val.i & 0x1f) <= 7) {
704 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
706 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
707 M_ISSL(REG_ITMP2, REG_ITMP1);
709 M_INTMOVE(REG_ITMP1, d);
713 emit_store_dst(jd, iptr, d);
716 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
719 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
721 M_INTMOVE(s1, REG_ITMP1);
722 M_INTMOVE(s2, REG_ITMP2);
723 M_IAND_IMM(0x1f, REG_ITMP2);
724 M_ISSR(REG_ITMP2, REG_ITMP1);
725 M_INTMOVE(REG_ITMP1, d);
726 emit_store_dst(jd, iptr, d);
729 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
730 /* sx.val.i = constant */
732 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
733 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
734 if (iptr->sx.val.i & 0x1f) {
735 M_INTMOVE(s1, REG_ITMP1)
736 if ((iptr->sx.val.i & 0x1f) <= 7) {
737 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
739 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
740 M_ISSR(REG_ITMP2, REG_ITMP1);
742 M_INTMOVE(REG_ITMP1, d);
746 emit_store_dst(jd, iptr, d);
749 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
754 M_INTMOVE(s1, REG_ITMP1);
755 M_INTMOVE(s2, REG_ITMP2);
756 M_IAND_IMM(0x1f, REG_ITMP2);
757 M_IUSR(REG_ITMP2, REG_ITMP1);
758 M_INTMOVE(REG_ITMP1, d);
759 emit_store_dst(jd, iptr, d);
762 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
763 /* sx.val.i = constant */
764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
766 if (iptr->sx.val.i & 0x1f) {
767 M_INTMOVE(s1, REG_ITMP1)
768 if ((iptr->sx.val.i & 0x1f) <= 7) {
769 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
771 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
772 M_IUSR(REG_ITMP2, REG_ITMP1);
774 M_INTMOVE(REG_ITMP1, d);
778 emit_store_dst(jd, iptr, d);
781 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
786 M_INTMOVE(s2, REG_ITMP2);
787 M_IAND(s1, REG_ITMP2);
788 M_INTMOVE(REG_ITMP2, d);
789 emit_store_dst(jd, iptr, d);
792 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
793 /* sx.val.i = constant */
795 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
797 M_INTMOVE(s1, REG_ITMP1);
798 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
799 M_INTMOVE(REG_ITMP1, d);
800 emit_store_dst(jd, iptr, d);
803 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
807 M_INTMOVE(s2, REG_ITMP2);
808 M_IOR(s1, REG_ITMP2);
809 M_INTMOVE(REG_ITMP2, d);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
814 /* sx.val.i = constant */
815 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
817 M_INTMOVE(s1, REG_ITMP1);
818 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
819 M_INTMOVE(REG_ITMP1, d);
820 emit_store_dst(jd, iptr, d);
823 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
824 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
825 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827 M_INTMOVE(s2, REG_ITMP2);
828 M_IXOR(s1, REG_ITMP2);
829 M_INTMOVE(REG_ITMP2, d);
830 emit_store_dst(jd, iptr, d);
833 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
834 /* sx.val.i = constant */
835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
836 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
837 M_INTMOVE(s1, REG_ITMP1);
838 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
839 M_INTMOVE(REG_ITMP1, d);
840 emit_store_dst(jd, iptr, d);
843 /* floating point operations ******************************************/
844 #if !defined(ENABLE_SOFTFLOAT)
845 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
847 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
848 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
852 M_BFUN(14); /* result is -1, branch to end */
853 M_BFLT(10); /* result is -1, branch to end */
855 M_BFEQ(4) /* result is 0, branch to end */
857 emit_store_dst(jd, iptr, d);
860 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
862 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
863 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
864 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
867 M_BFUN(16); /* result is +1, branch to end */
868 M_BFGT(14); /* result is +1, branch to end */
870 M_BFEQ(8) /* result is 0, branch to end */
872 emit_store_dst(jd, iptr, d);
875 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
876 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
877 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
878 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
879 M_FLTMOVE(s2, REG_FTMP2);
880 M_FMUL(s1, REG_FTMP2);
881 M_FLTMOVE(REG_FTMP2, d);
882 emit_store_dst(jd, iptr, d);
885 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
886 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
887 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
888 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
889 M_DBLMOVE(s2, REG_FTMP2);
890 M_DMUL(s1, REG_FTMP2);
891 M_DBLMOVE(REG_FTMP2, d);
892 emit_store_dst(jd, iptr, d);
895 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
896 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
897 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
898 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
899 M_FLTMOVE(s1, REG_FTMP1);
900 M_FDIV(s2, REG_FTMP1);
901 M_FLTMOVE(REG_FTMP1, d);
902 emit_store_dst(jd, iptr, d);
905 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
906 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
907 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
908 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
909 M_DBLMOVE(s1, REG_FTMP1);
910 M_DDIV(s2, REG_FTMP1);
911 M_DBLMOVE(REG_FTMP1, d);
912 emit_store_dst(jd, iptr, d);
915 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
916 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
917 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
918 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
919 M_FLTMOVE(s2, REG_FTMP2);
920 M_FADD(s1, REG_FTMP2);
921 M_FLTMOVE(REG_FTMP2, d);
922 emit_store_dst(jd, iptr, d);
925 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
926 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
927 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
928 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
929 M_DBLMOVE(s2, REG_FTMP2);
930 M_DADD(s1, REG_FTMP2);
931 M_DBLMOVE(REG_FTMP2, d);
932 emit_store_dst(jd, iptr, d);
935 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
936 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
937 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
938 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
939 M_FLTMOVE(s1, REG_FTMP1);
940 M_FSUB(s2, REG_FTMP1);
941 M_FLTMOVE(REG_FTMP1, d);
942 emit_store_dst(jd, iptr, d);
945 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
946 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
947 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
948 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
949 M_DBLMOVE(s1, REG_FTMP1);
950 M_DSUB(s2, REG_FTMP1);
951 M_DBLMOVE(REG_FTMP1, d);
952 emit_store_dst(jd, iptr, d);
955 case ICMD_F2D: /* ..., value ==> ..., (double) value */
956 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
957 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
959 emit_store_dst(jd, iptr, d);
962 case ICMD_D2F: /* ..., value ==> ..., (float) value */
963 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
964 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
966 emit_store_dst(jd, iptr, d);
969 case ICMD_FNEG: /* ..., value ==> ..., - value */
970 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
971 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
973 emit_store_dst(jd, iptr, d);
976 case ICMD_DNEG: /* ..., value ==> ..., - value */
977 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
978 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
980 emit_store_dst(jd, iptr, d);
985 /* load/store/copy/move operations ************************************/
987 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
988 case ICMD_ALOAD: /* s1 = local variable */
992 case ICMD_ISTORE: /* ..., value ==> ... */
1004 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1005 emit_copy(jd, iptr);
1009 case ICMD_ACONST: /* ... ==> ..., constant */
1010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1012 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1013 constant_classref *cr = iptr->sx.val.c.ref;;
1014 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1017 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1019 emit_store_dst(jd, iptr, d);
1021 /* BRANCH *************************************************************/
1023 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1025 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1026 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1028 #ifdef ENABLE_VERIFIER
1029 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1030 unresolved_class *uc = iptr->sx.s23.s2.uc;
1032 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1034 #endif /* ENABLE_VERIFIER */
1035 M_JSR_PCREL(2); /* get current PC */
1038 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1043 case ICMD_GOTO: /* ... ==> ... */
1044 case ICMD_RET: /* ... ==> ... */
1046 emit_br(cd, iptr->dst.block);
1050 case ICMD_JSR: /* ... ==> ... */
1052 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1058 case ICMD_IFNULL: /* ..., value ==> ... */
1059 case ICMD_IFNONNULL:
1060 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1061 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1063 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1071 case ICMD_IFEQ: /* ..., value ==> ... */
1073 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1074 assert (VAROP(iptr->s1)->type == TYPE_INT);
1075 M_ICMP_IMM(iptr->sx.val.i, s1);
1076 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1079 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1080 case ICMD_IF_ICMPNE:
1081 case ICMD_IF_ICMPLT:
1082 case ICMD_IF_ICMPGT:
1083 case ICMD_IF_ICMPLE:
1084 case ICMD_IF_ICMPGE:
1086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1087 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1089 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1092 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1093 case ICMD_IF_ACMPNE:
1095 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1096 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1098 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1102 /* MEMORY *************************************************************/
1104 case ICMD_GETSTATIC: /* ... ==> ..., value */
1106 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1107 uf = iptr->sx.s23.s3.uf;
1108 fieldtype = uf->fieldref->parseddesc.fd->type;
1111 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1114 fi = iptr->sx.s23.s3.fmiref->p.field;
1115 fieldtype = fi->type;
1116 disp = (intptr_t) fi->value;
1118 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
1119 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1124 M_AMOV_IMM(disp, REG_ATMP1);
1125 switch (fieldtype) {
1126 #if defined(ENABLE_SOFTFLOAT)
1130 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1131 M_ILD(d, REG_ATMP1, 0);
1134 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1135 M_ALD(d, REG_ATMP1, 0);
1137 #if defined(ENABLE_SOFTFLOAT)
1141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1142 M_LLD(d, REG_ATMP1, 0);
1144 #if !defined(ENABLE_SOFTFLOAT)
1146 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1147 M_FLD(d, REG_ATMP1, 0);
1150 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1151 M_DLD(d, REG_ATMP1, 0);
1155 emit_store_dst(jd, iptr, d);
1158 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1160 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1161 uf = iptr->sx.s23.s3.uf;
1162 fieldtype = uf->fieldref->parseddesc.fd->type;
1165 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1168 fi = iptr->sx.s23.s3.fmiref->p.field;
1169 fieldtype = fi->type;
1170 disp = (intptr_t) fi->value;
1172 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
1173 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
1177 M_AMOV_IMM(disp, REG_ATMP1);
1178 switch (fieldtype) {
1179 #if defined(ENABLE_SOFTFLOAT)
1183 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1184 M_IST(s1, REG_ATMP1, 0);
1186 #if defined(ENABLE_SOFTFLOAT)
1190 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1191 M_LST(s1, REG_ATMP1, 0);
1194 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1195 M_AST(s1, REG_ATMP1, 0);
1197 #if !defined(ENABLE_SOFTFLOAT)
1199 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1200 M_FST(s1, REG_ATMP1, 0);
1203 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1204 M_DST(s1, REG_ATMP1, 0);
1211 case ICMD_GETFIELD: /* ... ==> ..., value */
1213 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1215 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1216 uf = iptr->sx.s23.s3.uf;
1217 fieldtype = uf->fieldref->parseddesc.fd->type;
1220 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1223 fi = iptr->sx.s23.s3.fmiref->p.field;
1224 fieldtype = fi->type;
1228 /* implicit null-pointer check */
1229 switch (fieldtype) {
1230 #if defined(ENABLE_SOFTFLOAT)
1234 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1237 #if defined(ENABLE_SOFTFLOAT)
1241 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1248 #if !defined(ENABLE_SOFTFLOAT)
1250 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1254 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1259 emit_store_dst(jd, iptr, d);
1262 case ICMD_PUTFIELD: /* ..., value ==> ... */
1264 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1266 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1267 uf = iptr->sx.s23.s3.uf;
1268 fieldtype = uf->fieldref->parseddesc.fd->type;
1272 fi = iptr->sx.s23.s3.fmiref->p.field;
1273 fieldtype = fi->type;
1277 if (IS_INT_LNG_TYPE(fieldtype)) {
1278 if (IS_2_WORD_TYPE(fieldtype)) {
1279 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1281 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1284 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1287 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1288 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1290 /* implicit null-pointer check */
1291 switch (fieldtype) {
1292 #if defined(ENABLE_SOFTFLOAT)
1296 M_IST(s2, s1, disp);
1299 #if defined(ENABLE_SOFTFLOAT)
1303 M_LST(s2, s1, disp);
1306 M_AST(s2, s1, disp);
1308 #if !defined(ENABLE_SOFTFLOAT)
1310 M_FST(s2, s1, disp);
1313 M_DST(s2, s1, disp);
1319 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1321 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1322 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1323 /* implicit null-pointer check */
1324 M_ILD(d, s1, OFFSET(java_array_t, size));
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1330 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1331 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1332 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1333 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1334 M_INTMOVE(s2, REG_ITMP2);
1335 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1336 M_ADRMOVE(s1, REG_ATMP1);
1337 M_AADDINT(REG_ITMP2, REG_ATMP1);
1338 /* implicit null-pointer check */
1339 M_LBZX(REG_ATMP1, d);
1341 emit_store_dst(jd, iptr, d);
1344 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1346 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1347 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1348 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1349 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1350 M_INTMOVE(s2, REG_ITMP2);
1351 M_ISSL_IMM(1, REG_ITMP2);
1352 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1353 M_ADRMOVE(s1, REG_ATMP1);
1354 M_AADDINT(REG_ITMP2, REG_ATMP1);
1355 /* implicit null-pointer check */
1356 M_LHZX(REG_ATMP1, d);
1358 emit_store_dst(jd, iptr, d);
1361 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1363 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1364 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1366 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1367 M_INTMOVE(s2, REG_ITMP2);
1368 M_ISSL_IMM(1, REG_ITMP2);
1369 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1370 M_ADRMOVE(s1, REG_ATMP1);
1371 M_AADDINT(REG_ITMP2, REG_ATMP1);
1373 /* implicit null-pointer check */
1374 M_LHZX(REG_ATMP1, d);
1376 emit_store_dst(jd, iptr, d);
1379 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1381 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1382 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1383 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1384 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1385 M_INTMOVE(s2, REG_ITMP2);
1386 M_ISSL_IMM(2, REG_ITMP2);
1387 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1388 M_ADRMOVE(s1, REG_ATMP1);
1389 M_AADDINT(REG_ITMP2, REG_ATMP1);
1390 /* implicit null-pointer check */
1391 M_LWZX(REG_ATMP1, d);
1392 emit_store_dst(jd, iptr, d);
1395 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1396 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1397 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1398 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1399 /* implicit null-pointer check */
1400 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1401 M_INTMOVE(s2, REG_ITMP1);
1402 M_ISSL_IMM(3, REG_ITMP1);
1403 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1404 M_ADRMOVE(s1, REG_ATMP1);
1405 M_AADDINT(REG_ITMP1, REG_ATMP1);
1406 /* implicit null-pointer check */
1407 M_LLD(d, REG_ATMP1, 0);
1408 emit_store_dst(jd, iptr, d);
1411 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1412 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1413 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1414 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1415 M_INTMOVE(s2, REG_ITMP2);
1416 M_ISSL_IMM(2, REG_ITMP2);
1417 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1418 M_ADRMOVE(s1, REG_ATMP1);
1419 M_AADDINT(REG_ITMP2, REG_ATMP1);
1420 /* implicit null-pointer check */
1421 #if !defined(ENABLE_SOFTFLOAT)
1422 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1423 M_FLD(d, REG_ATMP1, 0);
1425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1426 M_LWZX(REG_ATMP1, d);
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1432 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1433 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1434 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1435 M_INTMOVE(s2, REG_ITMP2);
1436 M_ISSL_IMM(3, REG_ITMP2);
1437 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1438 M_ADRMOVE(s1, REG_ATMP1);
1439 M_AADDINT(REG_ITMP2, REG_ATMP1);
1440 /* implicit null-pointer check */
1441 #if !defined(ENABLE_SOFTFLOAT)
1442 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1443 M_DLD(d, REG_ATMP1, 0);
1445 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1446 M_LLD(d, REG_ATMP1, 0);
1448 emit_store_dst(jd, iptr, d);
1451 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1452 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1453 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1454 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1455 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1456 M_INTMOVE(s2, REG_ITMP2);
1457 M_ISSL_IMM(2, REG_ITMP2);
1458 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1459 M_ADRMOVE(s1, REG_ATMP1);
1460 M_AADDINT(REG_ITMP2, REG_ATMP1);
1462 /* implicit null-pointer check */
1463 M_LAX(REG_ATMP1, d);
1464 emit_store_dst(jd, iptr, d);
1468 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1469 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1470 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1471 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1472 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1473 M_INTMOVE(s2, REG_ITMP2);
1474 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1475 M_ADRMOVE(s1, REG_ATMP1);
1476 M_AADDINT(REG_ITMP2, REG_ATMP1);
1477 /* implicit null-pointer check */
1478 M_STBX(REG_ATMP1, s3);
1481 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1483 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1484 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1485 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1486 M_INTMOVE(s2, REG_ITMP2);
1487 M_ISSL_IMM(1, REG_ITMP2);
1488 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1489 M_ADRMOVE(s1, REG_ATMP1);
1490 M_AADDINT(REG_ITMP2, REG_ATMP1);
1491 /* implicit null-pointer check */
1492 M_STHX(REG_ATMP1, s3);
1495 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1496 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1497 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1498 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1499 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1500 M_INTMOVE(s2, REG_ITMP2);
1501 M_ISSL_IMM(1, REG_ITMP2);
1502 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1503 M_ADRMOVE(s1, REG_ATMP1);
1504 M_AADDINT(REG_ITMP2, REG_ATMP1);
1505 /* implicit null-pointer check */
1506 M_STHX(REG_ATMP1, s3);
1509 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1513 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1514 M_INTMOVE(s2, REG_ITMP2);
1515 M_ISSL_IMM(2, REG_ITMP2);
1516 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1517 M_ADRMOVE(s1, REG_ATMP1);
1518 M_AADDINT(REG_ITMP2, REG_ATMP1);
1519 /* implicit null-pointer check */
1520 M_STWX(REG_ATMP1, s3);
1523 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1524 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1525 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1526 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1528 M_INTMOVE(s2, REG_ITMP1);
1529 M_ISSL_IMM(3, REG_ITMP1);
1530 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1531 M_ADRMOVE(s1, REG_ATMP1);
1532 M_AADDINT(REG_ITMP1, REG_ATMP1);
1533 /* implicit null-pointer check */
1534 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1535 M_LST(s3, REG_ATMP1, 0);
1538 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1539 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1541 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1542 M_INTMOVE(s2, REG_ITMP2);
1543 M_ISSL_IMM(2, REG_ITMP2);
1544 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1545 M_ADRMOVE(s1, REG_ATMP1);
1546 M_AADDINT(REG_ITMP2, REG_ATMP1);
1547 /* implicit null-pointer check */
1548 #if !defined(ENABLE_SOFTFLOAT)
1549 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1550 M_FST(s3, REG_ATMP1, 0);
1552 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1553 M_STWX(REG_ATMP1, s3);
1557 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1559 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1560 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1561 M_INTMOVE(s2, REG_ITMP2);
1562 M_ISSL_IMM(3, REG_ITMP2);
1563 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1564 M_ADRMOVE(s1, REG_ATMP1);
1565 M_AADDINT(REG_ITMP2, REG_ATMP1);
1566 /* implicit null-pointer check */
1567 #if !defined(ENABLE_SOFTFLOAT)
1568 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1569 M_DST(s3, REG_ATMP1, 0);
1571 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1572 /* implicit null-pointer check */
1573 M_LST(s3, REG_ATMP1, 0);
1577 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1579 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1580 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1581 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1582 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1584 /* XXX what if array is NULL */
1585 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1587 M_AST(s1, REG_SP, 0*4);
1588 M_AST(s3, REG_SP, 1*4);
1589 M_JSR_IMM(BUILTIN_FAST_canstore);
1590 emit_arraystore_check(cd, iptr);
1592 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1593 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1594 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1595 M_INTMOVE(s2, REG_ITMP1);
1596 M_ISSL_IMM(2, REG_ITMP1);
1597 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1598 M_ADRMOVE(s1, REG_ATMP1);
1599 M_AADDINT(REG_ITMP1, REG_ATMP1);
1600 /* implicit null-pointer check */
1601 M_STAX(REG_ATMP1, s3);
1606 /* METHOD INVOCATION *********************************************************/
1607 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1608 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1610 bte = iptr->sx.s23.s3.bte;
1614 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1615 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1616 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1617 case ICMD_INVOKEINTERFACE:
1618 REPLACEMENT_POINT_INVOKE(cd, iptr);
1620 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1622 um = iptr->sx.s23.s3.um;
1623 md = um->methodref->parseddesc.md;
1626 lm = iptr->sx.s23.s3.fmiref->p.method;
1628 md = lm->parseddesc;
1631 s3 = md->paramcount;
1633 MCODECHECK((s3 << 1) + 64);
1635 /* copy arguments to stack */
1636 for (s3 = s3 - 1; s3 >= 0; s3--) {
1637 var = VAR(iptr->sx.s23.s2.args[s3]);
1638 /* already preallocated */
1639 if (var->flags & PREALLOC) continue;
1641 if (!md->params[s3].inmemory) assert(0);
1643 switch (var->type) {
1644 #if defined(ENABLE_SOFTFLOAT)
1648 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1649 M_LST(d, REG_SP, md->params[s3].regoff);
1651 #if defined(ENABLE_SOFTFLOAT)
1655 d = emit_load(jd, iptr, var, REG_ITMP1);
1656 M_IST(d, REG_SP, md->params[s3].regoff);
1659 d = emit_load(jd, iptr, var, REG_ATMP1);
1660 M_AST(d, REG_SP, md->params[s3].regoff);
1662 #if !defined(ENABLE_SOFTFLOAT)
1664 d = emit_load(jd, iptr, var, REG_FTMP1);
1665 M_FST(d, REG_SP, md->params[s3].regoff);
1668 d = emit_load(jd, iptr, var, REG_FTMP1);
1669 M_DST(d, REG_SP, md->params[s3].regoff);
1677 /* arguments in place now */
1680 if (bte->stub == NULL)
1681 disp = (ptrint) bte->fp;
1683 disp = (ptrint) bte->stub;
1684 d = md->returntype.type;
1687 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1690 case ICMD_INVOKESPECIAL:
1691 /* adress register for sure */
1692 M_ALD(REG_ATMP1, REG_SP, 0);
1693 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1695 case ICMD_INVOKESTATIC:
1697 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1699 M_AMOV_IMM(disp, REG_ATMP1);
1701 disp = lm->stubroutine;
1702 M_AMOV_IMM(disp, REG_ATMP1);
1705 /* generate the actual call */
1707 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1711 case ICMD_INVOKEVIRTUAL:
1713 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1716 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1718 /* load object pointer (==argument 0) */
1719 M_ALD(REG_ATMP1, REG_SP, 0);
1720 /* implicit null-pointer check */
1721 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1722 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1723 /* generate the actual call */
1726 case ICMD_INVOKEINTERFACE:
1728 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1733 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
1734 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1736 /* load object pointer (==argument 0) */
1737 M_ALD(REG_ATMP1, REG_SP, 0);
1739 /* implicit null-pointer check */
1740 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1741 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1742 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1744 /* generate the actual call */
1746 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1750 } /* switch (iptr->opc) */
1752 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1753 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1755 /* store return value */
1756 d = md->returntype.type;
1759 case TYPE_VOID: break;
1760 #if defined(ENABLE_SOFTFLOAT)
1764 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1765 M_INTMOVE(REG_RESULT, s1);
1767 #if defined(ENABLE_SOFTFLOAT)
1771 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1772 M_LNGMOVE(REG_RESULT_PACKED, s1);
1775 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1776 /* all stuff is returned in %d0 */
1777 M_INT2ADRMOVE(REG_RESULT, s1);
1779 #if !defined(ENABLE_SOFTFLOAT)
1781 * for BUILTINS float values are returned in %d0,%d1
1782 * within cacao we use %fp0 for that.
1785 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1786 if (iptr->opc == ICMD_BUILTIN) {
1787 M_INT2FLTMOVE(REG_FRESULT, s1);
1789 M_FLTMOVE(REG_FRESULT, s1);
1793 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1794 if (iptr->opc == ICMD_BUILTIN) {
1795 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1796 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1798 M_DBLMOVE(REG_FRESULT, s1);
1805 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1806 break; /* ICMD_INVOKE* */
1808 #if defined(ENABLE_SOFTFLOAT)
1811 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1813 REPLACEMENT_POINT_RETURN(cd, iptr);
1814 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1815 M_INTMOVE(s1, REG_RESULT);
1816 goto nowperformreturn;
1818 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1820 REPLACEMENT_POINT_RETURN(cd, iptr);
1821 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1822 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1823 M_ADR2INTMOVE(s1, REG_RESULT);
1825 #ifdef ENABLE_VERIFIER
1826 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1827 unresolved_class *uc = iptr->sx.s23.s2.uc;
1829 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1831 #endif /* ENABLE_VERIFIER */
1832 goto nowperformreturn;
1834 #if defined(ENABLE_SOFTFLOAT)
1837 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1838 REPLACEMENT_POINT_RETURN(cd, iptr);
1839 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1840 M_LNGMOVE(s1, REG_RESULT_PACKED);
1841 goto nowperformreturn;
1843 #if !defined(ENABLE_SOFTFLOAT)
1844 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1845 REPLACEMENT_POINT_RETURN(cd, iptr);
1846 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1847 M_FLTMOVE(s1, REG_FRESULT);
1848 goto nowperformreturn;
1851 REPLACEMENT_POINT_RETURN(cd, iptr);
1852 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1853 M_DBLMOVE(s1, REG_FRESULT);
1854 goto nowperformreturn;
1858 case ICMD_RETURN: /* ... ==> ... */
1860 REPLACEMENT_POINT_RETURN(cd, iptr);
1866 p = cd->stackframesize;
1868 /* call trace function */
1869 #if !defined(NDEBUG)
1870 emit_verbosecall_exit(jd);
1873 #if defined(ENABLE_THREADS)
1874 /* call lock_monitor_exit */
1875 if (checksync && code_is_synchronized(code)) {
1876 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1878 /* we need to save the proper return value */
1879 /* we do not care for the long -> doubel convert space here */
1880 switch (iptr->opc) {
1881 #if defined(ENABLE_SOFTFLOAT)
1885 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1887 #if defined(ENABLE_SOFTFLOAT)
1892 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1894 #if !defined(ENABLE_SOFTFLOAT)
1896 M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1899 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1904 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1905 M_JSR_IMM(LOCK_monitor_exit);
1907 /* and now restore the proper return value */
1908 switch (iptr->opc) {
1910 #if defined(ENABLE_SOFTFLOAT)
1914 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1916 #if defined(ENABLE_SOFTFLOAT)
1921 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1923 #if !defined(ENABLE_SOFTFLOAT)
1925 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1928 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1936 /* restore return address */
1938 if (!code_is_leafmethod(code)) {
1939 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1940 may have a displacement overflow. */
1942 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1946 /* restore saved registers */
1948 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1949 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1951 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1952 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1954 #if !defined(ENABLE_SOFTFLOAT)
1955 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1956 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1959 /* deallocate stack */
1960 M_AADD_IMM(cd->stackframesize, REG_SP);
1966 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1967 /* val.a: (classinfo*) superclass */
1969 /* superclass is an interface:
1971 * return (sub != NULL) &&
1972 * (sub->vftbl->interfacetablelength > super->index) &&
1973 * (sub->vftbl->interfacetable[-super->index] != NULL);
1975 * superclass is a class:
1977 * return ((sub != NULL) && (0
1978 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1979 * super->vftbl->diffvall));
1986 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1991 super = iptr->sx.s23.s3.c.cls;
1992 superindex = super->index;
1995 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1996 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1998 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
1999 assert(VAROP(iptr->dst)->type == TYPE_INT);
2003 /* if class is not resolved, check which code to call */
2005 if (super == NULL) {
2007 emit_label_beq(cd, BRANCH_LABEL_1);
2009 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2011 M_IMOV_IMM32(0, REG_ITMP3);
2012 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2013 emit_label_beq(cd, BRANCH_LABEL_2);
2016 /* interface instanceof code */
2018 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2019 if (super == NULL) {
2020 patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2023 emit_label_beq(cd, BRANCH_LABEL_3);
2026 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2027 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2028 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
2031 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
2037 emit_label_br(cd, BRANCH_LABEL_4);
2039 emit_label(cd, BRANCH_LABEL_3);
2042 /* class instanceof code */
2044 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2045 if (super == NULL) {
2046 emit_label(cd, BRANCH_LABEL_2);
2048 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2049 M_AMOV_IMM(0, REG_ATMP2);
2051 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2053 emit_label_beq(cd, BRANCH_LABEL_5);
2056 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2058 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2059 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2060 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2062 M_ISUB(REG_ITMP3, REG_ITMP1);
2063 M_ICMP(REG_ITMP2, REG_ITMP1);
2066 M_TPFW; /* overlaps next instruction */
2070 emit_label(cd, BRANCH_LABEL_5);
2073 if (super == NULL) {
2074 emit_label(cd, BRANCH_LABEL_1);
2075 emit_label(cd, BRANCH_LABEL_4);
2078 emit_store_dst(jd, iptr, d);
2082 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2083 /* val.a: (classinfo*) superclass */
2085 /* superclass is an interface:
2087 * OK if ((sub == NULL) ||
2088 * (sub->vftbl->interfacetablelength > super->index) &&
2089 * (sub->vftbl->interfacetable[-super->index] != NULL));
2091 * superclass is a class:
2093 * OK if ((sub == NULL) || (0
2094 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2095 * super->vftbl->diffvall));
2098 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2099 /* object type cast-check */
2104 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2109 super = iptr->sx.s23.s3.c.cls;
2110 superindex = super->index;
2113 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2114 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2116 /* if class is not resolved, check which code to call */
2118 if (super == NULL) {
2120 emit_label_beq(cd, BRANCH_LABEL_1);
2122 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2124 M_IMOV_IMM32(0, REG_ITMP2);
2125 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2126 emit_label_beq(cd, BRANCH_LABEL_2);
2129 /* interface checkcast code */
2131 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2132 if (super == NULL) {
2133 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2136 emit_label_beq(cd, BRANCH_LABEL_3);
2139 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2140 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2142 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2144 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2146 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2148 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2151 emit_label_br(cd, BRANCH_LABEL_4);
2153 emit_label(cd, BRANCH_LABEL_3);
2156 /* class checkcast code */
2158 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2159 if (super == NULL) {
2160 emit_label(cd, BRANCH_LABEL_2);
2162 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2163 M_AMOV_IMM(0, REG_ATMP3);
2165 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2167 emit_label_beq(cd, BRANCH_LABEL_5);
2170 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2172 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2173 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2174 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2176 M_ISUB(REG_ITMP1, REG_ITMP3);
2177 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2179 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2182 emit_label(cd, BRANCH_LABEL_5);
2185 if (super == NULL) {
2186 emit_label(cd, BRANCH_LABEL_1);
2187 emit_label(cd, BRANCH_LABEL_4);
2190 d = codegen_reg_of_dst(jd, iptr, s1);
2192 /* array type cast-check */
2194 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2196 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2197 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2198 M_AMOV_IMM(0, REG_ATMP1);
2200 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2205 M_JSR_IMM(BUILTIN_arraycheckcast);
2206 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2208 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2211 d = codegen_reg_of_dst(jd, iptr, s1);
2213 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2215 emit_store_dst(jd, iptr, d);
2218 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2221 branch_target_t *table;
2223 table = iptr->dst.table;
2225 l = iptr->sx.s23.s2.tablelow;
2226 i = iptr->sx.s23.s3.tablehigh;
2228 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2229 M_INTMOVE(s1, REG_ITMP1);
2230 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2235 M_ICMP_IMM(i - 1, REG_ITMP1);
2236 emit_bugt(cd, table[0].block);
2238 /* build jump table top down and use address of lowest entry */
2242 dseg_add_target(cd, table->block);
2246 /* length of dataseg after last dseg_add_target is used by load */
2247 M_AMOV_IMM(0, REG_ATMP2);
2250 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2251 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2252 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2253 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2260 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2263 lookup_target_t *lookup;
2265 lookup = iptr->dst.lookup;
2267 i = iptr->sx.s23.s2.lookupcount;
2269 MCODECHECK((i<<2)+8);
2270 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2273 M_ICMP_IMM(lookup->value, s1);
2274 emit_beq(cd, lookup->target.block);
2278 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2283 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2285 /* check for negative sizes and copy sizes to stack if necessary */
2286 MCODECHECK((iptr->s1.argcount << 1) + 64);
2288 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2289 var = VAR(iptr->sx.s23.s2.args[s1]);
2291 /* Already Preallocated? */
2292 if (!(var->flags & PREALLOC)) {
2293 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2294 M_IST(s2, REG_SP, (s1 + 3) * 4);
2298 /* a0 = dimension count */
2299 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2300 M_IST(REG_ITMP1, REG_SP, 0*4);
2302 /* a1 = arraydescriptor */
2303 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2304 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2305 M_AMOV_IMM(0, REG_ATMP1);
2307 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2309 M_AST(REG_ATMP1, REG_SP, 1*4);
2311 /* a2 = pointer to dimensions = stack pointer */
2312 M_AMOV(REG_SP, REG_ATMP1);
2313 M_AADD_IMM(3*4, REG_ATMP1);
2314 M_AST(REG_ATMP1, REG_SP, 2*4);
2316 M_JSR_IMM(BUILTIN_multianewarray);
2318 /* check for exception before result assignment */
2319 emit_exception_check(cd, iptr);
2321 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2322 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2323 M_INT2ADRMOVE(REG_RESULT, d);
2324 emit_store_dst(jd, iptr, d);
2330 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2331 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2334 /* M_TPF; */ /* nop after each ICMD */
2335 } /* for each instruction */
2337 /* At the end of a basic block we may have to append some nops,
2338 because the patcher stub calling code might be longer than the
2339 actual instruction. So codepatching does not change the
2340 following block unintentionally. */
2342 if (cd->mcodeptr < cd->lastmcodeptr) {
2343 while (cd->mcodeptr < cd->lastmcodeptr) {
2349 } /* if (btpre->flags >= BBREACHED) */
2350 } /* for each basic block */
2352 /* generate stubs */
2353 emit_patcher_traps(jd);
2358 /* codegen_emit_stub_native ****************************************************
2360 Emits a stub routine which calls a native method.
2362 *******************************************************************************/
2364 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2373 /* get required compiler data */
2382 /* calc stackframe size */
2383 cd->stackframesize =
2384 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2385 sizeof(localref_table) / SIZEOF_VOID_P +
2387 1 + /* functionptr */
2388 4; /* args for codegen_start_native_call */
2390 /* create method header */
2391 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2392 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2393 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2394 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2395 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2398 M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
2400 /* put arguments for codegen_start_native_call onto stack */
2401 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2403 M_AMOV(REG_SP, REG_ATMP1);
2404 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2406 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2407 dseg_adddata(cd); /* this patches it */
2409 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2411 M_JSR_IMM(codegen_start_native_call);
2413 /* remember class argument */
2414 if (m->flags & ACC_STATIC)
2415 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2417 /* copy arguments into stackframe */
2418 for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) {
2419 t = md->paramtypes[i].type;
2420 /* all arguments via stack */
2421 assert(md->params[i].inmemory);
2423 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
2424 s2 = nmd->params[j].regoff;
2426 /* simply copy argument stack */
2427 M_ILD(REG_ITMP1, REG_SP, s1);
2428 M_IST(REG_ITMP1, REG_SP, s2);
2429 if (IS_2_WORD_TYPE(t)) {
2430 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2431 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2435 /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
2436 if (m->flags & ACC_NATIVE) {
2437 /* for static function class as second arg */
2438 if (m->flags & ACC_STATIC)
2439 M_AST(REG_ATMP3, REG_SP, 1 * 4);
2441 /* env ist first argument */
2442 M_AMOV_IMM(VM_get_jnienv(), REG_ATMP1);
2443 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2446 /* call the native function */
2447 M_AMOV_IMM(f, REG_ATMP2);
2450 /* save return value */
2451 switch (md->returntype.type) {
2452 case TYPE_VOID: break;
2454 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2457 M_IST(REG_D1, REG_SP, 2 * 8);
2463 M_IST(REG_D0, REG_SP, 2 * 8); /* XXX can this be correct ? */
2469 /* remove native stackframe info */
2470 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2472 M_AMOV(REG_SP, REG_ATMP1);
2473 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2475 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2476 dseg_adddata(cd); /* this patches it */
2478 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2480 M_JSR_IMM(codegen_finish_native_call);
2482 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2483 /* restore return value */
2484 switch (md->returntype.type) {
2485 case TYPE_VOID: break;
2488 case TYPE_LNG: M_ILD(REG_D1, REG_SP, 2 * 8);
2493 M_ILD(REG_D0, REG_SP, 2 * 8); /* XXX */
2498 #if !defined(ENABLE_SOFTFLOAT)
2499 /* additionally load values into floating points registers
2500 * as cacao jit code expects them there */
2501 switch (md->returntype.type) {
2503 M_FLD(REG_D0, REG_SP, 2 * 8);
2506 M_DLD(REG_D0, REG_SP, 2 * 8); /* XXX */
2510 /* restore saved registers */
2512 M_AADD_IMM(cd->stackframesize*8, REG_SP);
2513 /* check for exception */
2518 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2520 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2521 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2522 M_JMP_IMM(asm_handle_nat_exception);
2524 /* should never be reached from within jit code*/
2530 * These are local overrides for various environment variables in Emacs.
2531 * Please do not remove this and leave it at the end of the file, where
2532 * Emacs will automagically detect them.
2533 * ---------------------------------------------------------------------
2536 * indent-tabs-mode: t
2540 * vim:noexpandtab:sw=4:ts=4: