1 /* src/vm/jit/m68k/codegen.c
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "vm/jit/m68k/codegen.h"
38 #include "vm/jit/m68k/emit.h"
40 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/localref.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/stringlocal.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/patcher-common.h"
56 #include "vm/jit/dseg.h"
57 #include "vm/jit/linenumbertable.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/abi.h"
61 #include "vm/jit/parse.h"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.h"
64 #include "vm/jit/stacktrace.h"
65 #include "vm/jit/md.h"
67 #include "vmcore/loader.h"
68 #include "vmcore/options.h"
69 #include "vmcore/utf8.h"
72 bool codegen_emit(jitdata *jd)
78 s4 len, s1, s2, s3, d, disp;
83 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
84 unresolved_method *um;
85 builtintable_entry *bte;
92 /* get required compiler data */
99 /* prevent compiler warnings */
107 /* save calle saved registers */
108 s4 savedregs_num = 0;
110 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
111 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
112 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
114 cd->stackframesize = rd->memuse + savedregs_num;
116 /* we always add 2 stack slots.
117 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
118 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
119 * on the other hand we could use 2 words when a builtin returns a doulbe which are
120 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
121 * so we always _need_ at least 2 slots, and this keeps the code simple */
122 cd->stackframesize += 2;
124 cd->stackframesize *= 8; /* we use 8 byte stack slots */
127 #if defined(ENABLE_THREADS)
128 /* we need additional space to save argument of monitor_enter */
129 if (checksync && code_is_synchronized(code)) {
130 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
131 cd->stackframesize += 2;
133 cd->stackframesize += 1;
139 /* create method header */
140 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
141 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
143 code->synchronizedoffset = rd->memuse * 8;
145 /* REMOVEME: We still need it for exception handling in assembler. */
147 if (code_is_leafmethod(code))
148 (void) dseg_add_unique_s4(cd, 1);
150 (void) dseg_add_unique_s4(cd, 0);
152 /* XXX we use the IntSave a split field for the adr now */
153 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
154 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
156 #if defined(ENABLE_PROFILING)
161 emit_verbosecall_enter(jd);
163 /* create stack frame */
164 M_AADD_IMM(-(cd->stackframesize), REG_SP);
166 /* save used callee saved registers */
167 p = cd->stackframesize;
168 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
169 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
171 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
172 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
174 #if !defined(ENABLE_SOFTFLOAT)
175 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
176 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
179 assert(FLT_SAV_CNT == 0);
180 assert(rd->savfltreguse == 0);
182 /* take arguments out of stack frame */
184 for (p = 0, l = 0; p < md->paramcount; p++) {
185 t = md->paramtypes[p].type;
186 varindex = jd->local_map[l * 5 + t];
189 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
192 if (varindex == UNUSED)
197 s1 = md->params[p].regoff;
198 assert(md->params[p].inmemory); /* all args are on stack */
201 #if defined(ENABLE_SOFTFLOAT)
207 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
208 if (IS_2_WORD_TYPE(t)) {
209 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
211 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
213 } else { /* stack arg -> spilled */
214 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
215 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
216 if (IS_2_WORD_TYPE(t)) {
217 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
218 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
222 #if !defined(ENABLE_SOFTFLOAT)
225 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
226 if (IS_2_WORD_TYPE(t)) {
227 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
229 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
231 } else { /* stack-arg -> spilled */
232 if (IS_2_WORD_TYPE(t)) {
233 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
234 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
236 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
237 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
241 #endif /* SOFTFLOAT */
243 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
244 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
245 } else { /* stack-arg -> spilled */
246 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
247 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
252 } /* end for argument out of stack*/
254 #if defined(ENABLE_THREADS)
255 /* call lock_monitor_enter function */
256 if (checksync && code_is_synchronized(code)) {
257 if (m->flags & ACC_STATIC) {
258 M_AMOV_IMM((&m->class->object.header), REG_ATMP1);
260 /* for non-static case the first arg is the object */
261 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
264 M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
267 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
268 M_AST(REG_ATMP1, REG_SP, 0 * 4);
269 M_JSR_IMM(LOCK_monitor_enter);
275 /* create replacement points */
276 REPLACEMENT_POINTS_INIT(cd, jd);
278 /* foreach basic block */
279 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
281 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
283 if (bptr->flags >= BBREACHED) {
285 /* branch resolving */
286 codegen_resolve_branchrefs(cd, bptr);
288 /* handle replacement points */
289 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
291 #if defined(ENABLE_PROFILING)
294 /* FIXME there are still some constrcuts to copy in here */
296 #if defined(ENABLE_LSRA)
300 /* copy interface registers to their destination */
306 var = VAR(bptr->invars[len]);
307 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
308 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
309 M_ADRMOVE(REG_ATMP1_XPTR, d);
310 emit_store(jd, NULL, var, d);
313 assert((var->flags & INOUT));
317 /* walk through all instructions */
321 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
322 if (iptr->line != currentline) {
323 linenumbertable_list_entry_add(cd, iptr->line);
324 currentline = iptr->line;
327 MCODECHECK(1024); /* 1kB should be enough */
330 case ICMD_NOP: /* ... ==> ... */
331 case ICMD_POP: /* ..., value ==> ... */
332 case ICMD_POP2: /* ..., value, value ==> ... */
335 case ICMD_INLINE_START:
337 REPLACEMENT_POINT_INLINE_START(cd, iptr);
340 case ICMD_INLINE_BODY:
342 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
343 linenumbertable_list_entry_add_intern(cd, iptr);
344 linenumbertable_list_entry_add(cd, iptr->line);
347 case ICMD_INLINE_END:
349 linenumbertable_list_entry_add_inline(cd, iptr);
350 linenumbertable_list_entry_add(cd, iptr->line);
353 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
356 assert(VAROP(iptr->s1)->type == TYPE_ADR);
357 emit_nullpointer_check(cd, iptr, s1);
361 /* CONST **************************************************************/
362 case ICMD_ICONST: /* ... ==> ..., constant */
363 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
364 M_IMOV_IMM(iptr->sx.val.i, d);
365 emit_store_dst(jd, iptr, d);
368 case ICMD_LCONST: /* ... ==> ..., constant */
370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
371 LCONST(iptr->sx.val.l, d);
372 emit_store_dst(jd, iptr, d);
375 case ICMD_FCONST: /* ... ==> ..., constant */
377 #if defined(ENABLE_SOFTFLOAT)
378 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
379 M_IMOV_IMM(iptr->sx.val.i, d);
380 emit_store_dst(jd, iptr, d);
382 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
383 FCONST(iptr->sx.val.i, d);
384 emit_store_dst(jd, iptr, d);
388 case ICMD_DCONST: /* ... ==> ..., constant */
390 #if defined(ENABLE_SOFTFLOAT)
391 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
392 LCONST(iptr->sx.val.l, d);
393 emit_store_dst(jd, iptr, d);
395 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
396 disp = dseg_add_double(cd, iptr->sx.val.d);
397 M_AMOV_IMM(0, REG_ATMP1);
399 M_DLD(d, REG_ATMP1, disp);
400 emit_store_dst(jd, iptr, d);
405 /* some long operations *********************************************/
406 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
407 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
408 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
410 M_INTMOVE(s2, REG_ITMP1);
411 M_IADD(s1, REG_ITMP1); /* low word */
412 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
413 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
414 M_INTMOVE(s2, REG_ITMP2);
415 M_IADDX(s1, REG_ITMP2); /* high word */
416 emit_store_dst(jd, iptr, d);
419 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
420 /* sx.val.l = constant */
421 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
422 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
423 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
425 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
427 s3 = iptr->sx.val.l & 0xffffffff;
428 M_INTMOVE(s1, REG_ITMP1);
429 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
431 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
432 M_LNGMOVE(REG_ITMP12_PACKED, d);
433 emit_store_dst(jd, iptr, d);
436 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
437 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
438 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
439 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
440 M_INTMOVE(s1, REG_ITMP1);
441 M_ISUB(s2, REG_ITMP1); /* low word */
442 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
443 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
444 M_INTMOVE(s1, REG_ITMP2);
445 M_ISUBX(s2, REG_ITMP2); /* high word */
446 emit_store_dst(jd, iptr, d);
449 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
450 /* sx.val.l = constant */
451 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
452 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
455 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
457 s3 = (-iptr->sx.val.l) & 0xffffffff;
458 M_INTMOVE(s1, REG_ITMP1);
459 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
461 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
462 M_LNGMOVE(REG_ITMP12_PACKED, d);
463 emit_store_dst(jd, iptr, d);
466 case ICMD_LNEG: /* ..., value ==> ..., - value */
467 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
468 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
469 M_LNGMOVE(s1, REG_ITMP12_PACKED);
470 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
471 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
472 M_LNGMOVE(REG_ITMP12_PACKED, d);
473 emit_store_dst(jd, iptr, d);
476 /* integer operations ************************************************/
477 case ICMD_INEG: /* ..., value ==> ..., - value */
479 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
481 M_INTMOVE(s1, REG_ITMP1);
483 M_INTMOVE(REG_ITMP1, d);
484 emit_store_dst(jd, iptr, d);
487 case ICMD_I2L: /* ..., value ==> ..., value */
489 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
490 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
491 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
493 M_ISET(GET_HIGH_REG(d));
495 M_ICLR(GET_HIGH_REG(d));
497 emit_store_dst(jd, iptr, d);
500 case ICMD_L2I: /* ..., value ==> ..., value */
502 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
503 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
505 emit_store_dst(jd, iptr, d);
507 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
512 emit_store_dst(jd, iptr, d);
515 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
520 emit_store_dst(jd, iptr, d);
523 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
528 emit_store_dst(jd, iptr, d);
533 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
536 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
538 M_INTMOVE(s2, REG_ITMP2);
539 M_IADD(s1, REG_ITMP2);
540 M_INTMOVE(REG_ITMP2, d);
541 emit_store_dst(jd, iptr, d);
544 /* s1.localindex = variable, sx.val.i = constant*/
549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
551 M_INTMOVE(s1, REG_ITMP1);
552 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
553 M_INTMOVE(REG_ITMP1, d);
554 emit_store_dst(jd, iptr, d);
557 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
562 M_INTMOVE(s1, REG_ITMP1);
563 M_ISUB(s2, REG_ITMP1);
564 M_INTMOVE(REG_ITMP1, d);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
569 /* sx.val.i = constant */
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
573 M_INTMOVE(s1, REG_ITMP1);
574 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
575 M_INTMOVE(REG_ITMP1, d);
576 emit_store_dst(jd, iptr, d);
579 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
581 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
583 emit_arithmetic_check(cd, iptr, s2);
584 M_INTMOVE(s1, REG_ITMP1);
585 M_IDIV(s2, REG_ITMP1);
586 M_INTMOVE(REG_ITMP1, d);
587 emit_store_dst(jd, iptr, d);
590 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
593 M_INTMOVE(s1, REG_ITMP1);
597 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
599 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
600 M_ISSR(REG_ITMP2, REG_ITMP1);
601 M_INTMOVE(REG_ITMP1, d);
602 emit_store_dst(jd, iptr, d);
605 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
608 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
609 emit_arithmetic_check(cd, iptr, s2);
611 M_ICMP_IMM(0x80000000, s1);
616 M_TPFL; /* hides the next instruction */
617 M_IREM(s2, s1, REG_ITMP3);
619 M_INTMOVE(REG_ITMP3, d);
621 emit_store_dst(jd, iptr, d);
624 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
625 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628 M_IMOV(s1, REG_ITMP1);
632 M_IAND_IMM(iptr->sx.val.i, d);
634 M_BGE(2 + 2 + 6 + 2);
635 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
637 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
640 emit_store_dst(jd, iptr, d);
644 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
645 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
647 bte = iptr->sx.s23.s3.bte;
650 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
651 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
652 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
653 /* XXX could be optimized */
654 emit_arithmetic_check(cd, iptr, REG_ITMP3);
656 M_LST(s2, REG_SP, 2 * 4);
657 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
658 M_LST(s1, REG_SP, 0 * 4);
662 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
663 M_LNGMOVE(REG_RESULT_PACKED, d);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
669 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
670 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672 M_INTMOVE(s2, REG_ITMP2);
673 M_IMUL(s1, REG_ITMP2);
674 M_INTMOVE(REG_ITMP2, d);
675 emit_store_dst(jd, iptr, d);
678 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
679 /* sx.val.i = constant */
680 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
682 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
683 M_IMUL(s1, REG_ITMP2);
684 M_INTMOVE(REG_ITMP2, d);
685 emit_store_dst(jd, iptr, d);
688 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
691 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
693 M_INTMOVE(s1, REG_ITMP1);
694 M_INTMOVE(s2, REG_ITMP2);
695 M_IAND_IMM(0x1f, REG_ITMP2);
696 M_ISSL(REG_ITMP2, REG_ITMP1);
697 M_INTMOVE(REG_ITMP1, d);
698 emit_store_dst(jd, iptr, d);
701 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
702 /* sx.val.i = constant */
704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
705 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
706 if (iptr->sx.val.i & 0x1f) {
707 M_INTMOVE(s1, REG_ITMP1)
708 if ((iptr->sx.val.i & 0x1f) <= 7) {
709 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
711 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
712 M_ISSL(REG_ITMP2, REG_ITMP1);
714 M_INTMOVE(REG_ITMP1, d);
718 emit_store_dst(jd, iptr, d);
721 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
726 M_INTMOVE(s1, REG_ITMP1);
727 M_INTMOVE(s2, REG_ITMP2);
728 M_IAND_IMM(0x1f, REG_ITMP2);
729 M_ISSR(REG_ITMP2, REG_ITMP1);
730 M_INTMOVE(REG_ITMP1, d);
731 emit_store_dst(jd, iptr, d);
734 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
735 /* sx.val.i = constant */
737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
739 if (iptr->sx.val.i & 0x1f) {
740 M_INTMOVE(s1, REG_ITMP1)
741 if ((iptr->sx.val.i & 0x1f) <= 7) {
742 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
744 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
745 M_ISSR(REG_ITMP2, REG_ITMP1);
747 M_INTMOVE(REG_ITMP1, d);
751 emit_store_dst(jd, iptr, d);
754 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
757 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
759 M_INTMOVE(s1, REG_ITMP1);
760 M_INTMOVE(s2, REG_ITMP2);
761 M_IAND_IMM(0x1f, REG_ITMP2);
762 M_IUSR(REG_ITMP2, REG_ITMP1);
763 M_INTMOVE(REG_ITMP1, d);
764 emit_store_dst(jd, iptr, d);
767 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
768 /* sx.val.i = constant */
769 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
771 if (iptr->sx.val.i & 0x1f) {
772 M_INTMOVE(s1, REG_ITMP1)
773 if ((iptr->sx.val.i & 0x1f) <= 7) {
774 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
776 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
777 M_IUSR(REG_ITMP2, REG_ITMP1);
779 M_INTMOVE(REG_ITMP1, d);
783 emit_store_dst(jd, iptr, d);
786 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
789 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791 M_INTMOVE(s2, REG_ITMP2);
792 M_IAND(s1, REG_ITMP2);
793 M_INTMOVE(REG_ITMP2, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
798 /* sx.val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
802 M_INTMOVE(s1, REG_ITMP1);
803 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
804 M_INTMOVE(REG_ITMP1, d);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
812 M_INTMOVE(s2, REG_ITMP2);
813 M_IOR(s1, REG_ITMP2);
814 M_INTMOVE(REG_ITMP2, d);
815 emit_store_dst(jd, iptr, d);
818 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
819 /* sx.val.i = constant */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
822 M_INTMOVE(s1, REG_ITMP1);
823 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
824 M_INTMOVE(REG_ITMP1, d);
825 emit_store_dst(jd, iptr, d);
828 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
829 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
830 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
831 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
832 M_INTMOVE(s2, REG_ITMP2);
833 M_IXOR(s1, REG_ITMP2);
834 M_INTMOVE(REG_ITMP2, d);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
839 /* sx.val.i = constant */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
842 M_INTMOVE(s1, REG_ITMP1);
843 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
844 M_INTMOVE(REG_ITMP1, d);
845 emit_store_dst(jd, iptr, d);
848 /* floating point operations ******************************************/
849 #if !defined(ENABLE_SOFTFLOAT)
850 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
852 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
853 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
854 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
857 M_BFUN(14); /* result is -1, branch to end */
858 M_BFLT(10); /* result is -1, branch to end */
860 M_BFEQ(4) /* result is 0, branch to end */
862 emit_store_dst(jd, iptr, d);
865 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
867 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
868 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
872 M_BFUN(16); /* result is +1, branch to end */
873 M_BFGT(14); /* result is +1, branch to end */
875 M_BFEQ(8) /* result is 0, branch to end */
877 emit_store_dst(jd, iptr, d);
880 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
881 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
882 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
883 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
884 M_FLTMOVE(s2, REG_FTMP2);
885 M_FMUL(s1, REG_FTMP2);
886 M_FLTMOVE(REG_FTMP2, d);
887 emit_store_dst(jd, iptr, d);
890 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
891 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
892 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
893 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
894 M_DBLMOVE(s2, REG_FTMP2);
895 M_DMUL(s1, REG_FTMP2);
896 M_DBLMOVE(REG_FTMP2, d);
897 emit_store_dst(jd, iptr, d);
900 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
901 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
902 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
903 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
904 M_FLTMOVE(s1, REG_FTMP1);
905 M_FDIV(s2, REG_FTMP1);
906 M_FLTMOVE(REG_FTMP1, d);
907 emit_store_dst(jd, iptr, d);
910 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
911 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
912 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
913 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
914 M_DBLMOVE(s1, REG_FTMP1);
915 M_DDIV(s2, REG_FTMP1);
916 M_DBLMOVE(REG_FTMP1, d);
917 emit_store_dst(jd, iptr, d);
920 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
921 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
922 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
923 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
924 M_FLTMOVE(s2, REG_FTMP2);
925 M_FADD(s1, REG_FTMP2);
926 M_FLTMOVE(REG_FTMP2, d);
927 emit_store_dst(jd, iptr, d);
930 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
931 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
932 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
933 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
934 M_DBLMOVE(s2, REG_FTMP2);
935 M_DADD(s1, REG_FTMP2);
936 M_DBLMOVE(REG_FTMP2, d);
937 emit_store_dst(jd, iptr, d);
940 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
941 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
942 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
943 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
944 M_FLTMOVE(s1, REG_FTMP1);
945 M_FSUB(s2, REG_FTMP1);
946 M_FLTMOVE(REG_FTMP1, d);
947 emit_store_dst(jd, iptr, d);
950 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
951 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
952 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
953 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
954 M_DBLMOVE(s1, REG_FTMP1);
955 M_DSUB(s2, REG_FTMP1);
956 M_DBLMOVE(REG_FTMP1, d);
957 emit_store_dst(jd, iptr, d);
960 case ICMD_F2D: /* ..., value ==> ..., (double) value */
961 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
962 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
964 emit_store_dst(jd, iptr, d);
967 case ICMD_D2F: /* ..., value ==> ..., (float) value */
968 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
969 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
971 emit_store_dst(jd, iptr, d);
974 case ICMD_FNEG: /* ..., value ==> ..., - value */
975 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
976 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
978 emit_store_dst(jd, iptr, d);
981 case ICMD_DNEG: /* ..., value ==> ..., - value */
982 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
983 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
985 emit_store_dst(jd, iptr, d);
990 /* load/store/copy/move operations ************************************/
992 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
993 case ICMD_ALOAD: /* s1 = local variable */
997 case ICMD_ISTORE: /* ..., value ==> ... */
1004 emit_copy(jd, iptr);
1009 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1010 emit_copy(jd, iptr);
1014 case ICMD_ACONST: /* ... ==> ..., constant */
1015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1017 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1018 constant_classref *cr = iptr->sx.val.c.ref;;
1019 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1022 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1024 emit_store_dst(jd, iptr, d);
1026 /* BRANCH *************************************************************/
1028 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1030 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1031 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1033 #ifdef ENABLE_VERIFIER
1034 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1035 unresolved_class *uc = iptr->sx.s23.s2.uc;
1037 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1039 #endif /* ENABLE_VERIFIER */
1040 M_JSR_PCREL(2); /* get current PC */
1043 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1048 case ICMD_GOTO: /* ... ==> ... */
1049 case ICMD_RET: /* ... ==> ... */
1051 emit_br(cd, iptr->dst.block);
1055 case ICMD_JSR: /* ... ==> ... */
1057 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1063 case ICMD_IFNULL: /* ..., value ==> ... */
1064 case ICMD_IFNONNULL:
1065 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1066 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1068 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1076 case ICMD_IFEQ: /* ..., value ==> ... */
1078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079 assert (VAROP(iptr->s1)->type == TYPE_INT);
1080 M_ICMP_IMM(iptr->sx.val.i, s1);
1081 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1084 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1085 case ICMD_IF_ICMPNE:
1086 case ICMD_IF_ICMPLT:
1087 case ICMD_IF_ICMPGT:
1088 case ICMD_IF_ICMPLE:
1089 case ICMD_IF_ICMPGE:
1091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1092 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1094 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1097 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1098 case ICMD_IF_ACMPNE:
1100 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1101 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1103 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1107 /* MEMORY *************************************************************/
1109 case ICMD_GETSTATIC: /* ... ==> ..., value */
1111 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1112 uf = iptr->sx.s23.s3.uf;
1113 fieldtype = uf->fieldref->parseddesc.fd->type;
1116 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1119 fi = iptr->sx.s23.s3.fmiref->p.field;
1120 fieldtype = fi->type;
1121 disp = (intptr_t) fi->value;
1123 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1124 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1129 M_AMOV_IMM(disp, REG_ATMP1);
1130 switch (fieldtype) {
1131 #if defined(ENABLE_SOFTFLOAT)
1135 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1136 M_ILD(d, REG_ATMP1, 0);
1139 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1140 M_ALD(d, REG_ATMP1, 0);
1142 #if defined(ENABLE_SOFTFLOAT)
1146 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1147 M_LLD(d, REG_ATMP1, 0);
1149 #if !defined(ENABLE_SOFTFLOAT)
1151 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1152 M_FLD(d, REG_ATMP1, 0);
1155 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1156 M_DLD(d, REG_ATMP1, 0);
1160 emit_store_dst(jd, iptr, d);
1163 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1165 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1166 uf = iptr->sx.s23.s3.uf;
1167 fieldtype = uf->fieldref->parseddesc.fd->type;
1170 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1173 fi = iptr->sx.s23.s3.fmiref->p.field;
1174 fieldtype = fi->type;
1175 disp = (intptr_t) fi->value;
1177 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1178 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1182 M_AMOV_IMM(disp, REG_ATMP1);
1183 switch (fieldtype) {
1184 #if defined(ENABLE_SOFTFLOAT)
1188 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1189 M_IST(s1, REG_ATMP1, 0);
1191 #if defined(ENABLE_SOFTFLOAT)
1195 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1196 M_LST(s1, REG_ATMP1, 0);
1199 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1200 M_AST(s1, REG_ATMP1, 0);
1202 #if !defined(ENABLE_SOFTFLOAT)
1204 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1205 M_FST(s1, REG_ATMP1, 0);
1208 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1209 M_DST(s1, REG_ATMP1, 0);
1216 case ICMD_GETFIELD: /* ... ==> ..., value */
1218 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1220 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1221 uf = iptr->sx.s23.s3.uf;
1222 fieldtype = uf->fieldref->parseddesc.fd->type;
1225 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1228 fi = iptr->sx.s23.s3.fmiref->p.field;
1229 fieldtype = fi->type;
1233 /* implicit null-pointer check */
1234 switch (fieldtype) {
1235 #if defined(ENABLE_SOFTFLOAT)
1239 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1242 #if defined(ENABLE_SOFTFLOAT)
1246 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1250 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1253 #if !defined(ENABLE_SOFTFLOAT)
1255 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1259 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1264 emit_store_dst(jd, iptr, d);
1267 case ICMD_PUTFIELD: /* ..., value ==> ... */
1269 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1271 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1272 uf = iptr->sx.s23.s3.uf;
1273 fieldtype = uf->fieldref->parseddesc.fd->type;
1277 fi = iptr->sx.s23.s3.fmiref->p.field;
1278 fieldtype = fi->type;
1282 if (IS_INT_LNG_TYPE(fieldtype)) {
1283 if (IS_2_WORD_TYPE(fieldtype)) {
1284 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1286 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1289 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1292 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1293 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1295 /* implicit null-pointer check */
1296 switch (fieldtype) {
1297 #if defined(ENABLE_SOFTFLOAT)
1301 M_IST(s2, s1, disp);
1304 #if defined(ENABLE_SOFTFLOAT)
1308 M_LST(s2, s1, disp);
1311 M_AST(s2, s1, disp);
1313 #if !defined(ENABLE_SOFTFLOAT)
1315 M_FST(s2, s1, disp);
1318 M_DST(s2, s1, disp);
1324 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1326 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1327 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1328 /* implicit null-pointer check */
1329 M_ILD(d, s1, OFFSET(java_array_t, size));
1330 emit_store_dst(jd, iptr, d);
1333 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1335 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1336 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1337 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1338 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1339 M_INTMOVE(s2, REG_ITMP2);
1340 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1341 M_ADRMOVE(s1, REG_ATMP1);
1342 M_AADDINT(REG_ITMP2, REG_ATMP1);
1343 /* implicit null-pointer check */
1344 M_LBZX(REG_ATMP1, d);
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1351 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1354 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1355 M_INTMOVE(s2, REG_ITMP2);
1356 M_ISSL_IMM(1, REG_ITMP2);
1357 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1358 M_ADRMOVE(s1, REG_ATMP1);
1359 M_AADDINT(REG_ITMP2, REG_ATMP1);
1360 /* implicit null-pointer check */
1361 M_LHZX(REG_ATMP1, d);
1363 emit_store_dst(jd, iptr, d);
1366 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1368 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1369 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1371 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1372 M_INTMOVE(s2, REG_ITMP2);
1373 M_ISSL_IMM(1, REG_ITMP2);
1374 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1375 M_ADRMOVE(s1, REG_ATMP1);
1376 M_AADDINT(REG_ITMP2, REG_ATMP1);
1378 /* implicit null-pointer check */
1379 M_LHZX(REG_ATMP1, d);
1381 emit_store_dst(jd, iptr, d);
1384 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1386 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1387 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1388 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1389 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1390 M_INTMOVE(s2, REG_ITMP2);
1391 M_ISSL_IMM(2, REG_ITMP2);
1392 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1393 M_ADRMOVE(s1, REG_ATMP1);
1394 M_AADDINT(REG_ITMP2, REG_ATMP1);
1395 /* implicit null-pointer check */
1396 M_LWZX(REG_ATMP1, d);
1397 emit_store_dst(jd, iptr, d);
1400 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1401 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1402 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1403 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1404 /* implicit null-pointer check */
1405 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1406 M_INTMOVE(s2, REG_ITMP1);
1407 M_ISSL_IMM(3, REG_ITMP1);
1408 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1409 M_ADRMOVE(s1, REG_ATMP1);
1410 M_AADDINT(REG_ITMP1, REG_ATMP1);
1411 /* implicit null-pointer check */
1412 M_LLD(d, REG_ATMP1, 0);
1413 emit_store_dst(jd, iptr, d);
1416 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1417 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1418 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1419 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1420 M_INTMOVE(s2, REG_ITMP2);
1421 M_ISSL_IMM(2, REG_ITMP2);
1422 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1423 M_ADRMOVE(s1, REG_ATMP1);
1424 M_AADDINT(REG_ITMP2, REG_ATMP1);
1425 /* implicit null-pointer check */
1426 #if !defined(ENABLE_SOFTFLOAT)
1427 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1428 M_FLD(d, REG_ATMP1, 0);
1430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1431 M_LWZX(REG_ATMP1, d);
1433 emit_store_dst(jd, iptr, d);
1436 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1437 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1438 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1439 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1440 M_INTMOVE(s2, REG_ITMP2);
1441 M_ISSL_IMM(3, REG_ITMP2);
1442 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1443 M_ADRMOVE(s1, REG_ATMP1);
1444 M_AADDINT(REG_ITMP2, REG_ATMP1);
1445 /* implicit null-pointer check */
1446 #if !defined(ENABLE_SOFTFLOAT)
1447 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1448 M_DLD(d, REG_ATMP1, 0);
1450 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1451 M_LLD(d, REG_ATMP1, 0);
1453 emit_store_dst(jd, iptr, d);
1456 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1457 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1458 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1459 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1460 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1461 M_INTMOVE(s2, REG_ITMP2);
1462 M_ISSL_IMM(2, REG_ITMP2);
1463 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1464 M_ADRMOVE(s1, REG_ATMP1);
1465 M_AADDINT(REG_ITMP2, REG_ATMP1);
1467 /* implicit null-pointer check */
1468 M_LAX(REG_ATMP1, d);
1469 emit_store_dst(jd, iptr, d);
1473 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1474 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1475 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1476 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1477 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1478 M_INTMOVE(s2, REG_ITMP2);
1479 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1480 M_ADRMOVE(s1, REG_ATMP1);
1481 M_AADDINT(REG_ITMP2, REG_ATMP1);
1482 /* implicit null-pointer check */
1483 M_STBX(REG_ATMP1, s3);
1486 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1487 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1488 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1489 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1490 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1491 M_INTMOVE(s2, REG_ITMP2);
1492 M_ISSL_IMM(1, REG_ITMP2);
1493 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1494 M_ADRMOVE(s1, REG_ATMP1);
1495 M_AADDINT(REG_ITMP2, REG_ATMP1);
1496 /* implicit null-pointer check */
1497 M_STHX(REG_ATMP1, s3);
1500 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1501 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1502 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1503 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1504 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1505 M_INTMOVE(s2, REG_ITMP2);
1506 M_ISSL_IMM(1, REG_ITMP2);
1507 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1508 M_ADRMOVE(s1, REG_ATMP1);
1509 M_AADDINT(REG_ITMP2, REG_ATMP1);
1510 /* implicit null-pointer check */
1511 M_STHX(REG_ATMP1, s3);
1514 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1517 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1518 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1519 M_INTMOVE(s2, REG_ITMP2);
1520 M_ISSL_IMM(2, REG_ITMP2);
1521 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1522 M_ADRMOVE(s1, REG_ATMP1);
1523 M_AADDINT(REG_ITMP2, REG_ATMP1);
1524 /* implicit null-pointer check */
1525 M_STWX(REG_ATMP1, s3);
1528 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1529 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1531 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1533 M_INTMOVE(s2, REG_ITMP1);
1534 M_ISSL_IMM(3, REG_ITMP1);
1535 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1536 M_ADRMOVE(s1, REG_ATMP1);
1537 M_AADDINT(REG_ITMP1, REG_ATMP1);
1538 /* implicit null-pointer check */
1539 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1540 M_LST(s3, REG_ATMP1, 0);
1543 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1545 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1546 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1547 M_INTMOVE(s2, REG_ITMP2);
1548 M_ISSL_IMM(2, REG_ITMP2);
1549 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1550 M_ADRMOVE(s1, REG_ATMP1);
1551 M_AADDINT(REG_ITMP2, REG_ATMP1);
1552 /* implicit null-pointer check */
1553 #if !defined(ENABLE_SOFTFLOAT)
1554 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1555 M_FST(s3, REG_ATMP1, 0);
1557 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1558 M_STWX(REG_ATMP1, s3);
1562 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1565 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1566 M_INTMOVE(s2, REG_ITMP2);
1567 M_ISSL_IMM(3, REG_ITMP2);
1568 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1569 M_ADRMOVE(s1, REG_ATMP1);
1570 M_AADDINT(REG_ITMP2, REG_ATMP1);
1571 /* implicit null-pointer check */
1572 #if !defined(ENABLE_SOFTFLOAT)
1573 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1574 M_DST(s3, REG_ATMP1, 0);
1576 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1577 /* implicit null-pointer check */
1578 M_LST(s3, REG_ATMP1, 0);
1582 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1584 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1585 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1586 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1587 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1589 /* XXX what if array is NULL */
1590 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1592 M_AST(s1, REG_SP, 0*4);
1593 M_AST(s3, REG_SP, 1*4);
1594 M_JSR_IMM(BUILTIN_FAST_canstore);
1595 emit_arraystore_check(cd, iptr);
1597 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1598 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1599 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1600 M_INTMOVE(s2, REG_ITMP1);
1601 M_ISSL_IMM(2, REG_ITMP1);
1602 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1603 M_ADRMOVE(s1, REG_ATMP1);
1604 M_AADDINT(REG_ITMP1, REG_ATMP1);
1605 /* implicit null-pointer check */
1606 M_STAX(REG_ATMP1, s3);
1611 /* METHOD INVOCATION *********************************************************/
1612 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1613 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1615 bte = iptr->sx.s23.s3.bte;
1619 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1620 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1621 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1622 case ICMD_INVOKEINTERFACE:
1623 REPLACEMENT_POINT_INVOKE(cd, iptr);
1625 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1627 um = iptr->sx.s23.s3.um;
1628 md = um->methodref->parseddesc.md;
1631 lm = iptr->sx.s23.s3.fmiref->p.method;
1633 md = lm->parseddesc;
1636 s3 = md->paramcount;
1638 MCODECHECK((s3 << 1) + 64);
1640 /* copy arguments to stack */
1641 for (s3 = s3 - 1; s3 >= 0; s3--) {
1642 var = VAR(iptr->sx.s23.s2.args[s3]);
1643 /* already preallocated */
1644 if (var->flags & PREALLOC) continue;
1646 if (!md->params[s3].inmemory) assert(0);
1648 switch (var->type) {
1649 #if defined(ENABLE_SOFTFLOAT)
1653 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1654 M_LST(d, REG_SP, md->params[s3].regoff);
1656 #if defined(ENABLE_SOFTFLOAT)
1660 d = emit_load(jd, iptr, var, REG_ITMP1);
1661 M_IST(d, REG_SP, md->params[s3].regoff);
1664 d = emit_load(jd, iptr, var, REG_ATMP1);
1665 M_AST(d, REG_SP, md->params[s3].regoff);
1667 #if !defined(ENABLE_SOFTFLOAT)
1669 d = emit_load(jd, iptr, var, REG_FTMP1);
1670 M_FST(d, REG_SP, md->params[s3].regoff);
1673 d = emit_load(jd, iptr, var, REG_FTMP1);
1674 M_DST(d, REG_SP, md->params[s3].regoff);
1682 /* arguments in place now */
1685 if (bte->stub == NULL)
1686 disp = (ptrint) bte->fp;
1688 disp = (ptrint) bte->stub;
1689 d = md->returntype.type;
1692 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1695 case ICMD_INVOKESPECIAL:
1696 /* adress register for sure */
1697 M_ALD(REG_ATMP1, REG_SP, 0);
1698 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1700 case ICMD_INVOKESTATIC:
1702 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1704 M_AMOV_IMM(disp, REG_ATMP1);
1706 disp = lm->stubroutine;
1707 M_AMOV_IMM(disp, REG_ATMP1);
1710 /* generate the actual call */
1712 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1716 case ICMD_INVOKEVIRTUAL:
1718 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1721 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1723 /* load object pointer (==argument 0) */
1724 M_ALD(REG_ATMP1, REG_SP, 0);
1725 /* implicit null-pointer check */
1726 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1727 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1728 /* generate the actual call */
1731 case ICMD_INVOKEINTERFACE:
1733 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1738 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1739 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1741 /* load object pointer (==argument 0) */
1742 M_ALD(REG_ATMP1, REG_SP, 0);
1744 /* implicit null-pointer check */
1745 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1746 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1747 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1749 /* generate the actual call */
1751 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1755 } /* switch (iptr->opc) */
1757 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1758 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1760 /* store return value */
1761 d = md->returntype.type;
1764 case TYPE_VOID: break;
1765 #if defined(ENABLE_SOFTFLOAT)
1769 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1770 M_INTMOVE(REG_RESULT, s1);
1772 #if defined(ENABLE_SOFTFLOAT)
1776 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1777 M_LNGMOVE(REG_RESULT_PACKED, s1);
1780 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1781 /* all stuff is returned in %d0 */
1782 M_INT2ADRMOVE(REG_RESULT, s1);
1784 #if !defined(ENABLE_SOFTFLOAT)
1786 * for BUILTINS float values are returned in %d0,%d1
1787 * within cacao we use %fp0 for that.
1790 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1791 if (iptr->opc == ICMD_BUILTIN) {
1792 M_INT2FLTMOVE(REG_FRESULT, s1);
1794 M_FLTMOVE(REG_FRESULT, s1);
1798 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1799 if (iptr->opc == ICMD_BUILTIN) {
1800 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1801 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1803 M_DBLMOVE(REG_FRESULT, s1);
1810 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1811 break; /* ICMD_INVOKE* */
1813 #if defined(ENABLE_SOFTFLOAT)
1816 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1818 REPLACEMENT_POINT_RETURN(cd, iptr);
1819 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1820 M_INTMOVE(s1, REG_RESULT);
1821 goto nowperformreturn;
1823 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1825 REPLACEMENT_POINT_RETURN(cd, iptr);
1826 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1827 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1828 M_ADR2INTMOVE(s1, REG_RESULT);
1830 #ifdef ENABLE_VERIFIER
1831 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1832 unresolved_class *uc = iptr->sx.s23.s2.uc;
1834 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1836 #endif /* ENABLE_VERIFIER */
1837 goto nowperformreturn;
1839 #if defined(ENABLE_SOFTFLOAT)
1842 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1843 REPLACEMENT_POINT_RETURN(cd, iptr);
1844 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1845 M_LNGMOVE(s1, REG_RESULT_PACKED);
1846 goto nowperformreturn;
1848 #if !defined(ENABLE_SOFTFLOAT)
1849 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1850 REPLACEMENT_POINT_RETURN(cd, iptr);
1851 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1852 M_FLTMOVE(s1, REG_FRESULT);
1853 goto nowperformreturn;
1856 REPLACEMENT_POINT_RETURN(cd, iptr);
1857 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1858 M_DBLMOVE(s1, REG_FRESULT);
1859 goto nowperformreturn;
1863 case ICMD_RETURN: /* ... ==> ... */
1865 REPLACEMENT_POINT_RETURN(cd, iptr);
1871 p = cd->stackframesize;
1873 /* call trace function */
1874 #if !defined(NDEBUG)
1875 emit_verbosecall_exit(jd);
1878 #if defined(ENABLE_THREADS)
1879 /* call lock_monitor_exit */
1880 if (checksync && code_is_synchronized(code)) {
1881 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1883 /* we need to save the proper return value */
1884 /* we do not care for the long -> doubel convert space here */
1885 switch (iptr->opc) {
1886 #if defined(ENABLE_SOFTFLOAT)
1890 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1892 #if defined(ENABLE_SOFTFLOAT)
1897 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1899 #if !defined(ENABLE_SOFTFLOAT)
1901 M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1904 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1909 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1910 M_JSR_IMM(LOCK_monitor_exit);
1912 /* and now restore the proper return value */
1913 switch (iptr->opc) {
1915 #if defined(ENABLE_SOFTFLOAT)
1919 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1921 #if defined(ENABLE_SOFTFLOAT)
1926 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1928 #if !defined(ENABLE_SOFTFLOAT)
1930 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1933 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1941 /* restore return address */
1943 if (!code_is_leafmethod(code)) {
1944 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1945 may have a displacement overflow. */
1947 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1951 /* restore saved registers */
1953 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1954 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1956 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1957 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1959 #if !defined(ENABLE_SOFTFLOAT)
1960 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1961 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1964 /* deallocate stack */
1965 M_AADD_IMM(cd->stackframesize, REG_SP);
1971 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1972 /* val.a: (classinfo*) superclass */
1974 /* superclass is an interface:
1976 * return (sub != NULL) &&
1977 * (sub->vftbl->interfacetablelength > super->index) &&
1978 * (sub->vftbl->interfacetable[-super->index] != NULL);
1980 * superclass is a class:
1982 * return ((sub != NULL) && (0
1983 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1984 * super->vftbl->diffvall));
1991 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1996 super = iptr->sx.s23.s3.c.cls;
1997 superindex = super->index;
2000 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2001 CODEGEN_CRITICAL_SECTION_NEW;
2003 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2004 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2006 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2007 assert(VAROP(iptr->dst)->type == TYPE_INT);
2011 /* if class is not resolved, check which code to call */
2013 if (super == NULL) {
2015 emit_label_beq(cd, BRANCH_LABEL_1);
2017 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2019 M_IMOV_IMM32(0, REG_ITMP3);
2020 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2021 emit_label_beq(cd, BRANCH_LABEL_2);
2024 /* interface instanceof code */
2026 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2027 if (super == NULL) {
2028 patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2031 emit_label_beq(cd, BRANCH_LABEL_3);
2034 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2035 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2036 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
2039 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
2045 emit_label_br(cd, BRANCH_LABEL_4);
2047 emit_label(cd, BRANCH_LABEL_3);
2050 /* class instanceof code */
2052 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2053 if (super == NULL) {
2054 emit_label(cd, BRANCH_LABEL_2);
2056 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2057 M_AMOV_IMM(0, REG_ATMP2);
2059 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2061 emit_label_beq(cd, BRANCH_LABEL_5);
2064 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2066 CODEGEN_CRITICAL_SECTION_START;
2068 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2069 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2070 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2072 CODEGEN_CRITICAL_SECTION_END;
2074 M_ISUB(REG_ITMP3, REG_ITMP1);
2075 M_ICMP(REG_ITMP2, REG_ITMP1);
2078 M_TPFW; /* overlaps next instruction */
2082 emit_label(cd, BRANCH_LABEL_5);
2085 if (super == NULL) {
2086 emit_label(cd, BRANCH_LABEL_1);
2087 emit_label(cd, BRANCH_LABEL_4);
2090 emit_store_dst(jd, iptr, d);
2094 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2095 /* val.a: (classinfo*) superclass */
2097 /* superclass is an interface:
2099 * OK if ((sub == NULL) ||
2100 * (sub->vftbl->interfacetablelength > super->index) &&
2101 * (sub->vftbl->interfacetable[-super->index] != NULL));
2103 * superclass is a class:
2105 * OK if ((sub == NULL) || (0
2106 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2107 * super->vftbl->diffvall));
2110 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2111 /* object type cast-check */
2116 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2121 super = iptr->sx.s23.s3.c.cls;
2122 superindex = super->index;
2125 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2126 CODEGEN_CRITICAL_SECTION_NEW;
2128 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2129 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2131 /* if class is not resolved, check which code to call */
2133 if (super == NULL) {
2135 emit_label_beq(cd, BRANCH_LABEL_1);
2137 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2139 M_IMOV_IMM32(0, REG_ITMP2);
2140 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2141 emit_label_beq(cd, BRANCH_LABEL_2);
2144 /* interface checkcast code */
2146 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2147 if (super == NULL) {
2148 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2151 emit_label_beq(cd, BRANCH_LABEL_3);
2154 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2155 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2157 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2159 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2161 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2163 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2166 emit_label_br(cd, BRANCH_LABEL_4);
2168 emit_label(cd, BRANCH_LABEL_3);
2171 /* class checkcast code */
2173 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2174 if (super == NULL) {
2175 emit_label(cd, BRANCH_LABEL_2);
2177 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2178 M_AMOV_IMM(0, REG_ATMP3);
2180 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2182 emit_label_beq(cd, BRANCH_LABEL_5);
2185 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2187 CODEGEN_CRITICAL_SECTION_START;
2189 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2190 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2191 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2193 CODEGEN_CRITICAL_SECTION_END;
2195 M_ISUB(REG_ITMP1, REG_ITMP3);
2196 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2198 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2201 emit_label(cd, BRANCH_LABEL_5);
2204 if (super == NULL) {
2205 emit_label(cd, BRANCH_LABEL_1);
2206 emit_label(cd, BRANCH_LABEL_4);
2209 d = codegen_reg_of_dst(jd, iptr, s1);
2211 /* array type cast-check */
2213 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2215 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2216 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2217 M_AMOV_IMM(0, REG_ATMP1);
2219 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2224 M_JSR_IMM(BUILTIN_arraycheckcast);
2225 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2227 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2230 d = codegen_reg_of_dst(jd, iptr, s1);
2232 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2234 emit_store_dst(jd, iptr, d);
2237 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2240 branch_target_t *table;
2242 table = iptr->dst.table;
2244 l = iptr->sx.s23.s2.tablelow;
2245 i = iptr->sx.s23.s3.tablehigh;
2247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2248 M_INTMOVE(s1, REG_ITMP1);
2249 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2254 M_ICMP_IMM(i - 1, REG_ITMP1);
2255 emit_bugt(cd, table[0].block);
2257 /* build jump table top down and use address of lowest entry */
2261 dseg_add_target(cd, table->block);
2265 /* length of dataseg after last dseg_add_target is used by load */
2266 M_AMOV_IMM(0, REG_ATMP2);
2269 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2270 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2271 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2272 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2279 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2282 lookup_target_t *lookup;
2284 lookup = iptr->dst.lookup;
2286 i = iptr->sx.s23.s2.lookupcount;
2288 MCODECHECK((i<<2)+8);
2289 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2292 M_ICMP_IMM(lookup->value, s1);
2293 emit_beq(cd, lookup->target.block);
2297 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2302 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2304 /* check for negative sizes and copy sizes to stack if necessary */
2305 MCODECHECK((iptr->s1.argcount << 1) + 64);
2307 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2308 var = VAR(iptr->sx.s23.s2.args[s1]);
2310 /* Already Preallocated? */
2311 if (!(var->flags & PREALLOC)) {
2312 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2313 M_IST(s2, REG_SP, (s1 + 3) * 4);
2317 /* a0 = dimension count */
2318 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2319 M_IST(REG_ITMP1, REG_SP, 0*4);
2321 /* a1 = arraydescriptor */
2322 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2323 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2324 M_AMOV_IMM(0, REG_ATMP1);
2326 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2328 M_AST(REG_ATMP1, REG_SP, 1*4);
2330 /* a2 = pointer to dimensions = stack pointer */
2331 M_AMOV(REG_SP, REG_ATMP1);
2332 M_AADD_IMM(3*4, REG_ATMP1);
2333 M_AST(REG_ATMP1, REG_SP, 2*4);
2335 M_JSR_IMM(BUILTIN_multianewarray);
2337 /* check for exception before result assignment */
2338 emit_exception_check(cd, iptr);
2340 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2341 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2342 M_INT2ADRMOVE(REG_RESULT, d);
2343 emit_store_dst(jd, iptr, d);
2349 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2350 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2353 /* M_TPF; */ /* nop after each ICMD */
2354 } /* for each instruction */
2356 /* At the end of a basic block we may have to append some nops,
2357 because the patcher stub calling code might be longer than the
2358 actual instruction. So codepatching does not change the
2359 following block unintentionally. */
2361 if (cd->mcodeptr < cd->lastmcodeptr) {
2362 while (cd->mcodeptr < cd->lastmcodeptr) {
2368 } /* if (btpre->flags >= BBREACHED) */
2369 } /* for each basic block */
2371 /* generate stubs */
2372 emit_patcher_traps(jd);
2377 /* codegen_emit_stub_native ****************************************************
2379 Emits a stub routine which calls a native method.
2381 *******************************************************************************/
2383 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2392 /* get required compiler data */
2401 /* calc stackframe size */
2402 cd->stackframesize =
2403 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2404 sizeof(localref_table) / SIZEOF_VOID_P +
2406 1 + /* functionptr */
2407 4; /* args for codegen_start_native_call */
2409 /* create method header */
2410 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2411 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2412 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2413 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2414 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2416 /* print call trace */
2417 #if !defined(NDEBUG)
2418 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2419 emit_verbosecall_enter(jd);
2424 M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
2426 /* get function address (this must happen before the stackframeinfo) */
2428 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, 0);
2431 M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2433 M_AST(REG_ATMP2, REG_SP, 4 * 4);
2435 /* put arguments for codegen_start_native_call onto stack */
2436 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2438 M_AMOV(REG_SP, REG_ATMP1);
2439 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2441 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2442 dseg_adddata(cd); /* this patches it */
2444 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2446 M_JSR_IMM(codegen_start_native_call);
2448 /* remember class argument */
2449 if (m->flags & ACC_STATIC)
2450 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2452 /* load function pointer */
2453 M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2455 /* copy arguments into stackframe */
2456 for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) {
2457 t = md->paramtypes[i].type;
2458 /* all arguments via stack */
2459 assert(md->params[i].inmemory);
2461 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
2462 s2 = nmd->params[j].regoff;
2464 /* simply copy argument stack */
2465 M_ILD(REG_ITMP1, REG_SP, s1);
2466 M_IST(REG_ITMP1, REG_SP, s2);
2467 if (IS_2_WORD_TYPE(t)) {
2468 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2469 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2473 /* for static function class as second arg */
2474 if (m->flags & ACC_STATIC)
2475 M_AST(REG_ATMP3, REG_SP, 1 * 4);
2477 /* env ist first argument */
2478 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2479 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2481 /* call the native function */
2484 /* save return value */
2485 switch (md->returntype.type) {
2486 case TYPE_VOID: break;
2488 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2491 M_IST(REG_D1, REG_SP, 2 * 8);
2497 M_IST(REG_D0, REG_SP, 2 * 8); /* XXX can this be correct ? */
2503 /* print call trace */
2504 #if ! defined(NDEBUG)
2505 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2506 emit_verbosecall_exit(jd);
2509 /* remove native stackframe info */
2510 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2512 M_AMOV(REG_SP, REG_ATMP1);
2513 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2515 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2516 dseg_adddata(cd); /* this patches it */
2518 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2520 M_JSR_IMM(codegen_finish_native_call);
2522 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2523 /* restore return value */
2524 switch (md->returntype.type) {
2525 case TYPE_VOID: break;
2528 case TYPE_LNG: M_ILD(REG_D1, REG_SP, 2 * 8);
2533 M_ILD(REG_D0, REG_SP, 2 * 8); /* XXX */
2538 #if !defined(ENABLE_SOFTFLOAT)
2539 /* additionally load values into floating points registers
2540 * as cacao jit code expects them there */
2541 switch (md->returntype.type) {
2543 M_FLD(REG_D0, REG_SP, 2 * 8);
2546 M_DLD(REG_D0, REG_SP, 2 * 8); /* XXX */
2550 /* restore saved registers */
2552 M_AADD_IMM(cd->stackframesize*8, REG_SP);
2553 /* check for exception */
2558 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2560 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2561 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2562 M_JMP_IMM(asm_handle_nat_exception);
2564 /* should never be reached from within jit code*/
2567 /* generate patcher stub call code */
2568 emit_patcher_traps(jd);
2573 * These are local overrides for various environment variables in Emacs.
2574 * Please do not remove this and leave it at the end of the file, where
2575 * Emacs will automagically detect them.
2576 * ---------------------------------------------------------------------
2579 * indent-tabs-mode: t
2583 * vim:noexpandtab:sw=4:ts=4: