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"
66 #include "vmcore/loader.h"
67 #include "vmcore/options.h"
68 #include "vmcore/utf8.h"
71 bool codegen_emit(jitdata *jd)
77 s4 len, s1, s2, s3, d, disp;
82 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
83 unresolved_method *um;
84 builtintable_entry *bte;
91 /* get required compiler data */
98 /* prevent compiler warnings */
106 /* save calle saved registers */
107 s4 savedregs_num = 0;
109 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
110 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
111 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
113 cd->stackframesize = rd->memuse + savedregs_num;
115 /* we always add 2 stack slots.
116 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
117 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
118 * on the other hand we could use 2 words when a builtin returns a doulbe which are
119 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
120 * so we always _need_ at least 2 slots, and this keeps the code simple */
121 cd->stackframesize += 2;
123 cd->stackframesize *= 8; /* we use 8 byte stack slots */
126 #if defined(ENABLE_THREADS)
127 /* we need additional space to save argument of monitor_enter */
128 if (checksync && code_is_synchronized(code)) {
129 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
130 cd->stackframesize += 2;
132 cd->stackframesize += 1;
138 /* create method header */
139 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
140 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
142 code->synchronizedoffset = rd->memuse * 8;
144 /* REMOVEME: We still need it for exception handling in assembler. */
146 if (code_is_leafmethod(code))
147 (void) dseg_add_unique_s4(cd, 1);
149 (void) dseg_add_unique_s4(cd, 0);
151 /* XXX we use the IntSave a split field for the adr now */
152 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
153 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
155 #if defined(ENABLE_PROFILING)
160 emit_verbosecall_enter(jd);
162 /* create stack frame */
163 M_AADD_IMM(-(cd->stackframesize), REG_SP);
165 /* save used callee saved registers */
166 p = cd->stackframesize;
167 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
168 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
170 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
171 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
173 #if !defined(ENABLE_SOFTFLOAT)
174 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
175 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
178 assert(FLT_SAV_CNT == 0);
179 assert(rd->savfltreguse == 0);
181 /* take arguments out of stack frame */
183 for (p = 0, l = 0; p < md->paramcount; p++) {
184 t = md->paramtypes[p].type;
185 varindex = jd->local_map[l * 5 + t];
188 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
191 if (varindex == UNUSED)
196 s1 = md->params[p].regoff;
197 assert(md->params[p].inmemory); /* all args are on stack */
200 #if defined(ENABLE_SOFTFLOAT)
206 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
207 if (IS_2_WORD_TYPE(t)) {
208 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
210 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
212 } else { /* stack arg -> spilled */
213 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
214 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
215 if (IS_2_WORD_TYPE(t)) {
216 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
217 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
221 #if !defined(ENABLE_SOFTFLOAT)
224 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
225 if (IS_2_WORD_TYPE(t)) {
226 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
228 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
230 } else { /* stack-arg -> spilled */
231 if (IS_2_WORD_TYPE(t)) {
232 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
233 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
235 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
236 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
240 #endif /* SOFTFLOAT */
242 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
243 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
244 } else { /* stack-arg -> spilled */
245 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
246 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
251 } /* end for argument out of stack*/
253 #if defined(ENABLE_THREADS)
254 /* call lock_monitor_enter function */
255 if (checksync && code_is_synchronized(code)) {
256 if (m->flags & ACC_STATIC) {
257 M_AMOV_IMM((&m->class->object.header), REG_ATMP1);
259 /* for non-static case the first arg is the object */
260 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
263 M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
266 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
267 M_AST(REG_ATMP1, REG_SP, 0 * 4);
268 M_JSR_IMM(LOCK_monitor_enter);
274 /* create replacement points */
275 REPLACEMENT_POINTS_INIT(cd, jd);
277 /* foreach basic block */
278 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
280 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
282 if (bptr->flags >= BBREACHED) {
284 /* branch resolving */
285 codegen_resolve_branchrefs(cd, bptr);
287 /* handle replacement points */
288 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
290 #if defined(ENABLE_PROFILING)
293 /* FIXME there are still some constrcuts to copy in here */
295 #if defined(ENABLE_LSRA)
299 /* copy interface registers to their destination */
305 var = VAR(bptr->invars[len]);
306 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
307 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
308 M_ADRMOVE(REG_ATMP1_XPTR, d);
309 emit_store(jd, NULL, var, d);
312 assert((var->flags & INOUT));
316 /* walk through all instructions */
320 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
321 if (iptr->line != currentline) {
322 linenumbertable_list_entry_add(cd, iptr->line);
323 currentline = iptr->line;
326 MCODECHECK(1024); /* 1kB should be enough */
329 case ICMD_NOP: /* ... ==> ... */
330 case ICMD_POP: /* ..., value ==> ... */
331 case ICMD_POP2: /* ..., value, value ==> ... */
334 case ICMD_INLINE_START:
336 REPLACEMENT_POINT_INLINE_START(cd, iptr);
339 case ICMD_INLINE_BODY:
341 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
342 linenumbertable_list_entry_add_intern(cd, iptr);
343 linenumbertable_list_entry_add(cd, iptr->line);
346 case ICMD_INLINE_END:
348 linenumbertable_list_entry_add_inline(cd, iptr);
349 linenumbertable_list_entry_add(cd, iptr->line);
352 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
354 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
355 assert(VAROP(iptr->s1)->type == TYPE_ADR);
356 emit_nullpointer_check(cd, iptr, s1);
360 /* CONST **************************************************************/
361 case ICMD_ICONST: /* ... ==> ..., constant */
362 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
363 M_IMOV_IMM(iptr->sx.val.i, d);
364 emit_store_dst(jd, iptr, d);
367 case ICMD_LCONST: /* ... ==> ..., constant */
369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
370 LCONST(iptr->sx.val.l, d);
371 emit_store_dst(jd, iptr, d);
374 case ICMD_FCONST: /* ... ==> ..., constant */
376 #if defined(ENABLE_SOFTFLOAT)
377 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
378 M_IMOV_IMM(iptr->sx.val.i, d);
379 emit_store_dst(jd, iptr, d);
381 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
382 FCONST(iptr->sx.val.i, d);
383 emit_store_dst(jd, iptr, d);
387 case ICMD_DCONST: /* ... ==> ..., constant */
389 #if defined(ENABLE_SOFTFLOAT)
390 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
391 LCONST(iptr->sx.val.l, d);
392 emit_store_dst(jd, iptr, d);
394 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
395 disp = dseg_add_double(cd, iptr->sx.val.d);
396 M_AMOV_IMM(0, REG_ATMP1);
398 M_DLD(d, REG_ATMP1, disp);
399 emit_store_dst(jd, iptr, d);
404 /* some long operations *********************************************/
405 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
406 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
407 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
408 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
409 M_INTMOVE(s2, REG_ITMP1);
410 M_IADD(s1, REG_ITMP1); /* low word */
411 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
412 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
413 M_INTMOVE(s2, REG_ITMP2);
414 M_IADDX(s1, REG_ITMP2); /* high word */
415 emit_store_dst(jd, iptr, d);
418 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
419 /* sx.val.l = constant */
420 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
421 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
424 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
426 s3 = iptr->sx.val.l & 0xffffffff;
427 M_INTMOVE(s1, REG_ITMP1);
428 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
430 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
431 M_LNGMOVE(REG_ITMP12_PACKED, d);
432 emit_store_dst(jd, iptr, d);
435 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
436 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
437 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
438 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
439 M_INTMOVE(s1, REG_ITMP1);
440 M_ISUB(s2, REG_ITMP1); /* low word */
441 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
442 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
443 M_INTMOVE(s1, REG_ITMP2);
444 M_ISUBX(s2, REG_ITMP2); /* high word */
445 emit_store_dst(jd, iptr, d);
448 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
449 /* sx.val.l = constant */
450 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
451 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
454 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
456 s3 = (-iptr->sx.val.l) & 0xffffffff;
457 M_INTMOVE(s1, REG_ITMP1);
458 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
460 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
461 M_LNGMOVE(REG_ITMP12_PACKED, d);
462 emit_store_dst(jd, iptr, d);
465 case ICMD_LNEG: /* ..., value ==> ..., - value */
466 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
468 M_LNGMOVE(s1, REG_ITMP12_PACKED);
469 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
470 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
471 M_LNGMOVE(REG_ITMP12_PACKED, d);
472 emit_store_dst(jd, iptr, d);
475 /* integer operations ************************************************/
476 case ICMD_INEG: /* ..., value ==> ..., - value */
478 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
479 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
480 M_INTMOVE(s1, REG_ITMP1);
482 M_INTMOVE(REG_ITMP1, d);
483 emit_store_dst(jd, iptr, d);
486 case ICMD_I2L: /* ..., value ==> ..., value */
488 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
489 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
490 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
492 M_ISET(GET_HIGH_REG(d));
494 M_ICLR(GET_HIGH_REG(d));
496 emit_store_dst(jd, iptr, d);
499 case ICMD_L2I: /* ..., value ==> ..., value */
501 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
502 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
504 emit_store_dst(jd, iptr, d);
506 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
527 emit_store_dst(jd, iptr, d);
532 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
536 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
537 M_INTMOVE(s2, REG_ITMP2);
538 M_IADD(s1, REG_ITMP2);
539 M_INTMOVE(REG_ITMP2, d);
540 emit_store_dst(jd, iptr, d);
543 /* s1.localindex = variable, sx.val.i = constant*/
548 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
549 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
550 M_INTMOVE(s1, REG_ITMP1);
551 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
552 M_INTMOVE(REG_ITMP1, d);
553 emit_store_dst(jd, iptr, d);
556 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
559 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
561 M_INTMOVE(s1, REG_ITMP1);
562 M_ISUB(s2, REG_ITMP1);
563 M_INTMOVE(REG_ITMP1, d);
564 emit_store_dst(jd, iptr, d);
567 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
568 /* sx.val.i = constant */
570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
572 M_INTMOVE(s1, REG_ITMP1);
573 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
574 M_INTMOVE(REG_ITMP1, d);
575 emit_store_dst(jd, iptr, d);
578 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
580 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
582 emit_arithmetic_check(cd, iptr, s2);
583 M_INTMOVE(s1, REG_ITMP1);
584 M_IDIV(s2, REG_ITMP1);
585 M_INTMOVE(REG_ITMP1, d);
586 emit_store_dst(jd, iptr, d);
589 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
592 M_INTMOVE(s1, REG_ITMP1);
596 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
598 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
599 M_ISSR(REG_ITMP2, REG_ITMP1);
600 M_INTMOVE(REG_ITMP1, d);
601 emit_store_dst(jd, iptr, d);
604 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
606 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
607 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
608 emit_arithmetic_check(cd, iptr, s2);
610 M_ICMP_IMM(0x80000000, s1);
615 M_TPFL; /* hides the next instruction */
616 M_IREM(s2, s1, REG_ITMP3);
618 M_INTMOVE(REG_ITMP3, d);
620 emit_store_dst(jd, iptr, d);
623 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 M_IMOV(s1, REG_ITMP1);
631 M_IAND_IMM(iptr->sx.val.i, d);
633 M_BGE(2 + 2 + 6 + 2);
634 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
636 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
639 emit_store_dst(jd, iptr, d);
643 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
644 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
646 bte = iptr->sx.s23.s3.bte;
649 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
650 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
651 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
652 /* XXX could be optimized */
653 emit_arithmetic_check(cd, iptr, REG_ITMP3);
655 M_LST(s2, REG_SP, 2 * 4);
656 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
657 M_LST(s1, REG_SP, 0 * 4);
661 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
662 M_LNGMOVE(REG_RESULT_PACKED, d);
663 emit_store_dst(jd, iptr, d);
666 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
671 M_INTMOVE(s2, REG_ITMP2);
672 M_IMUL(s1, REG_ITMP2);
673 M_INTMOVE(REG_ITMP2, d);
674 emit_store_dst(jd, iptr, d);
677 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
678 /* sx.val.i = constant */
679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
680 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
681 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
682 M_IMUL(s1, REG_ITMP2);
683 M_INTMOVE(REG_ITMP2, d);
684 emit_store_dst(jd, iptr, d);
687 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
692 M_INTMOVE(s1, REG_ITMP1);
693 M_INTMOVE(s2, REG_ITMP2);
694 M_IAND_IMM(0x1f, REG_ITMP2);
695 M_ISSL(REG_ITMP2, REG_ITMP1);
696 M_INTMOVE(REG_ITMP1, d);
697 emit_store_dst(jd, iptr, d);
700 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
701 /* sx.val.i = constant */
703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
705 if (iptr->sx.val.i & 0x1f) {
706 M_INTMOVE(s1, REG_ITMP1)
707 if ((iptr->sx.val.i & 0x1f) <= 7) {
708 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
710 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
711 M_ISSL(REG_ITMP2, REG_ITMP1);
713 M_INTMOVE(REG_ITMP1, d);
717 emit_store_dst(jd, iptr, d);
720 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
724 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
725 M_INTMOVE(s1, REG_ITMP1);
726 M_INTMOVE(s2, REG_ITMP2);
727 M_IAND_IMM(0x1f, REG_ITMP2);
728 M_ISSR(REG_ITMP2, REG_ITMP1);
729 M_INTMOVE(REG_ITMP1, d);
730 emit_store_dst(jd, iptr, d);
733 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
734 /* sx.val.i = constant */
736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
737 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
738 if (iptr->sx.val.i & 0x1f) {
739 M_INTMOVE(s1, REG_ITMP1)
740 if ((iptr->sx.val.i & 0x1f) <= 7) {
741 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
743 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
744 M_ISSR(REG_ITMP2, REG_ITMP1);
746 M_INTMOVE(REG_ITMP1, d);
750 emit_store_dst(jd, iptr, d);
753 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
756 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
757 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
758 M_INTMOVE(s1, REG_ITMP1);
759 M_INTMOVE(s2, REG_ITMP2);
760 M_IAND_IMM(0x1f, REG_ITMP2);
761 M_IUSR(REG_ITMP2, REG_ITMP1);
762 M_INTMOVE(REG_ITMP1, d);
763 emit_store_dst(jd, iptr, d);
766 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
767 /* sx.val.i = constant */
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
770 if (iptr->sx.val.i & 0x1f) {
771 M_INTMOVE(s1, REG_ITMP1)
772 if ((iptr->sx.val.i & 0x1f) <= 7) {
773 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
775 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
776 M_IUSR(REG_ITMP2, REG_ITMP1);
778 M_INTMOVE(REG_ITMP1, d);
782 emit_store_dst(jd, iptr, d);
785 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
790 M_INTMOVE(s2, REG_ITMP2);
791 M_IAND(s1, REG_ITMP2);
792 M_INTMOVE(REG_ITMP2, d);
793 emit_store_dst(jd, iptr, d);
796 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
797 /* sx.val.i = constant */
799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
800 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
801 M_INTMOVE(s1, REG_ITMP1);
802 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
803 M_INTMOVE(REG_ITMP1, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
809 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
811 M_INTMOVE(s2, REG_ITMP2);
812 M_IOR(s1, REG_ITMP2);
813 M_INTMOVE(REG_ITMP2, d);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
818 /* sx.val.i = constant */
819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
821 M_INTMOVE(s1, REG_ITMP1);
822 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
823 M_INTMOVE(REG_ITMP1, d);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
829 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
830 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
831 M_INTMOVE(s2, REG_ITMP2);
832 M_IXOR(s1, REG_ITMP2);
833 M_INTMOVE(REG_ITMP2, d);
834 emit_store_dst(jd, iptr, d);
837 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
838 /* sx.val.i = constant */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
841 M_INTMOVE(s1, REG_ITMP1);
842 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
843 M_INTMOVE(REG_ITMP1, d);
844 emit_store_dst(jd, iptr, d);
847 /* floating point operations ******************************************/
848 #if !defined(ENABLE_SOFTFLOAT)
849 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
851 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
852 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
853 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
856 M_BFUN(14); /* result is -1, branch to end */
857 M_BFLT(10); /* result is -1, branch to end */
859 M_BFEQ(4) /* result is 0, branch to end */
861 emit_store_dst(jd, iptr, d);
864 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
866 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
867 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
871 M_BFUN(16); /* result is +1, branch to end */
872 M_BFGT(14); /* result is +1, branch to end */
874 M_BFEQ(8) /* result is 0, branch to end */
876 emit_store_dst(jd, iptr, d);
879 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
880 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
881 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
882 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
883 M_FLTMOVE(s2, REG_FTMP2);
884 M_FMUL(s1, REG_FTMP2);
885 M_FLTMOVE(REG_FTMP2, d);
886 emit_store_dst(jd, iptr, d);
889 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
890 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
891 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
892 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
893 M_DBLMOVE(s2, REG_FTMP2);
894 M_DMUL(s1, REG_FTMP2);
895 M_DBLMOVE(REG_FTMP2, d);
896 emit_store_dst(jd, iptr, d);
899 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
900 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
901 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
902 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
903 M_FLTMOVE(s1, REG_FTMP1);
904 M_FDIV(s2, REG_FTMP1);
905 M_FLTMOVE(REG_FTMP1, d);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
910 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
911 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
912 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
913 M_DBLMOVE(s1, REG_FTMP1);
914 M_DDIV(s2, REG_FTMP1);
915 M_DBLMOVE(REG_FTMP1, d);
916 emit_store_dst(jd, iptr, d);
919 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
920 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
921 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
922 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
923 M_FLTMOVE(s2, REG_FTMP2);
924 M_FADD(s1, REG_FTMP2);
925 M_FLTMOVE(REG_FTMP2, d);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
930 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
931 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
932 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
933 M_DBLMOVE(s2, REG_FTMP2);
934 M_DADD(s1, REG_FTMP2);
935 M_DBLMOVE(REG_FTMP2, d);
936 emit_store_dst(jd, iptr, d);
939 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
940 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
941 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
942 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
943 M_FLTMOVE(s1, REG_FTMP1);
944 M_FSUB(s2, REG_FTMP1);
945 M_FLTMOVE(REG_FTMP1, d);
946 emit_store_dst(jd, iptr, d);
949 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
950 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
951 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
952 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
953 M_DBLMOVE(s1, REG_FTMP1);
954 M_DSUB(s2, REG_FTMP1);
955 M_DBLMOVE(REG_FTMP1, d);
956 emit_store_dst(jd, iptr, d);
959 case ICMD_F2D: /* ..., value ==> ..., (double) value */
960 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
961 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
963 emit_store_dst(jd, iptr, d);
966 case ICMD_D2F: /* ..., value ==> ..., (float) value */
967 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
968 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
970 emit_store_dst(jd, iptr, d);
973 case ICMD_FNEG: /* ..., value ==> ..., - value */
974 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
975 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
977 emit_store_dst(jd, iptr, d);
980 case ICMD_DNEG: /* ..., value ==> ..., - value */
981 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
982 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
984 emit_store_dst(jd, iptr, d);
989 /* load/store/copy/move operations ************************************/
991 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
992 case ICMD_ALOAD: /* s1 = local variable */
996 case ICMD_ISTORE: /* ..., value ==> ... */
1003 emit_copy(jd, iptr);
1008 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1009 emit_copy(jd, iptr);
1013 case ICMD_ACONST: /* ... ==> ..., constant */
1014 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1016 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1017 constant_classref *cr = iptr->sx.val.c.ref;;
1018 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1021 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1023 emit_store_dst(jd, iptr, d);
1025 /* BRANCH *************************************************************/
1027 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1029 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1030 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1032 #ifdef ENABLE_VERIFIER
1033 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1034 unresolved_class *uc = iptr->sx.s23.s2.uc;
1036 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1038 #endif /* ENABLE_VERIFIER */
1039 M_JSR_PCREL(2); /* get current PC */
1042 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1047 case ICMD_GOTO: /* ... ==> ... */
1048 case ICMD_RET: /* ... ==> ... */
1050 emit_br(cd, iptr->dst.block);
1054 case ICMD_JSR: /* ... ==> ... */
1056 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1062 case ICMD_IFNULL: /* ..., value ==> ... */
1063 case ICMD_IFNONNULL:
1064 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1065 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1067 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1075 case ICMD_IFEQ: /* ..., value ==> ... */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 assert (VAROP(iptr->s1)->type == TYPE_INT);
1079 M_ICMP_IMM(iptr->sx.val.i, s1);
1080 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1083 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1084 case ICMD_IF_ICMPNE:
1085 case ICMD_IF_ICMPLT:
1086 case ICMD_IF_ICMPGT:
1087 case ICMD_IF_ICMPLE:
1088 case ICMD_IF_ICMPGE:
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1093 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1096 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1097 case ICMD_IF_ACMPNE:
1099 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1100 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1102 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1106 /* MEMORY *************************************************************/
1108 case ICMD_GETSTATIC: /* ... ==> ..., value */
1110 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1111 uf = iptr->sx.s23.s3.uf;
1112 fieldtype = uf->fieldref->parseddesc.fd->type;
1115 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1118 fi = iptr->sx.s23.s3.fmiref->p.field;
1119 fieldtype = fi->type;
1120 disp = (intptr_t) fi->value;
1122 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1123 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1128 M_AMOV_IMM(disp, REG_ATMP1);
1129 switch (fieldtype) {
1130 #if defined(ENABLE_SOFTFLOAT)
1134 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1135 M_ILD(d, REG_ATMP1, 0);
1138 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1139 M_ALD(d, REG_ATMP1, 0);
1141 #if defined(ENABLE_SOFTFLOAT)
1145 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1146 M_LLD(d, REG_ATMP1, 0);
1148 #if !defined(ENABLE_SOFTFLOAT)
1150 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1151 M_FLD(d, REG_ATMP1, 0);
1154 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1155 M_DLD(d, REG_ATMP1, 0);
1159 emit_store_dst(jd, iptr, d);
1162 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1164 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1165 uf = iptr->sx.s23.s3.uf;
1166 fieldtype = uf->fieldref->parseddesc.fd->type;
1169 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
1172 fi = iptr->sx.s23.s3.fmiref->p.field;
1173 fieldtype = fi->type;
1174 disp = (intptr_t) fi->value;
1176 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1177 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1181 M_AMOV_IMM(disp, REG_ATMP1);
1182 switch (fieldtype) {
1183 #if defined(ENABLE_SOFTFLOAT)
1187 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1188 M_IST(s1, REG_ATMP1, 0);
1190 #if defined(ENABLE_SOFTFLOAT)
1194 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1195 M_LST(s1, REG_ATMP1, 0);
1198 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1199 M_AST(s1, REG_ATMP1, 0);
1201 #if !defined(ENABLE_SOFTFLOAT)
1203 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1204 M_FST(s1, REG_ATMP1, 0);
1207 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1208 M_DST(s1, REG_ATMP1, 0);
1215 case ICMD_GETFIELD: /* ... ==> ..., value */
1217 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1219 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1220 uf = iptr->sx.s23.s3.uf;
1221 fieldtype = uf->fieldref->parseddesc.fd->type;
1224 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1227 fi = iptr->sx.s23.s3.fmiref->p.field;
1228 fieldtype = fi->type;
1232 /* implicit null-pointer check */
1233 switch (fieldtype) {
1234 #if defined(ENABLE_SOFTFLOAT)
1238 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1241 #if defined(ENABLE_SOFTFLOAT)
1245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1252 #if !defined(ENABLE_SOFTFLOAT)
1254 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1258 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1263 emit_store_dst(jd, iptr, d);
1266 case ICMD_PUTFIELD: /* ..., value ==> ... */
1268 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1270 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1271 uf = iptr->sx.s23.s3.uf;
1272 fieldtype = uf->fieldref->parseddesc.fd->type;
1276 fi = iptr->sx.s23.s3.fmiref->p.field;
1277 fieldtype = fi->type;
1281 if (IS_INT_LNG_TYPE(fieldtype)) {
1282 if (IS_2_WORD_TYPE(fieldtype)) {
1283 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1285 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1288 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1291 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1292 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1294 /* implicit null-pointer check */
1295 switch (fieldtype) {
1296 #if defined(ENABLE_SOFTFLOAT)
1300 M_IST(s2, s1, disp);
1303 #if defined(ENABLE_SOFTFLOAT)
1307 M_LST(s2, s1, disp);
1310 M_AST(s2, s1, disp);
1312 #if !defined(ENABLE_SOFTFLOAT)
1314 M_FST(s2, s1, disp);
1317 M_DST(s2, s1, disp);
1323 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1325 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1326 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1327 /* implicit null-pointer check */
1328 M_ILD(d, s1, OFFSET(java_array_t, size));
1329 emit_store_dst(jd, iptr, d);
1332 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1334 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1335 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1337 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1338 M_INTMOVE(s2, REG_ITMP2);
1339 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1340 M_ADRMOVE(s1, REG_ATMP1);
1341 M_AADDINT(REG_ITMP2, REG_ATMP1);
1342 /* implicit null-pointer check */
1343 M_LBZX(REG_ATMP1, d);
1345 emit_store_dst(jd, iptr, d);
1348 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1350 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1351 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1352 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1353 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1354 M_INTMOVE(s2, REG_ITMP2);
1355 M_ISSL_IMM(1, REG_ITMP2);
1356 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1357 M_ADRMOVE(s1, REG_ATMP1);
1358 M_AADDINT(REG_ITMP2, REG_ATMP1);
1359 /* implicit null-pointer check */
1360 M_LHZX(REG_ATMP1, d);
1362 emit_store_dst(jd, iptr, d);
1365 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1367 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1368 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1370 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1371 M_INTMOVE(s2, REG_ITMP2);
1372 M_ISSL_IMM(1, REG_ITMP2);
1373 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1374 M_ADRMOVE(s1, REG_ATMP1);
1375 M_AADDINT(REG_ITMP2, REG_ATMP1);
1377 /* implicit null-pointer check */
1378 M_LHZX(REG_ATMP1, d);
1380 emit_store_dst(jd, iptr, d);
1383 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1385 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1386 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1388 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1389 M_INTMOVE(s2, REG_ITMP2);
1390 M_ISSL_IMM(2, REG_ITMP2);
1391 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1392 M_ADRMOVE(s1, REG_ATMP1);
1393 M_AADDINT(REG_ITMP2, REG_ATMP1);
1394 /* implicit null-pointer check */
1395 M_LWZX(REG_ATMP1, d);
1396 emit_store_dst(jd, iptr, d);
1399 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1400 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1401 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1403 /* implicit null-pointer check */
1404 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1405 M_INTMOVE(s2, REG_ITMP1);
1406 M_ISSL_IMM(3, REG_ITMP1);
1407 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1408 M_ADRMOVE(s1, REG_ATMP1);
1409 M_AADDINT(REG_ITMP1, REG_ATMP1);
1410 /* implicit null-pointer check */
1411 M_LLD(d, REG_ATMP1, 0);
1412 emit_store_dst(jd, iptr, d);
1415 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1416 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1417 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1418 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1419 M_INTMOVE(s2, REG_ITMP2);
1420 M_ISSL_IMM(2, REG_ITMP2);
1421 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1422 M_ADRMOVE(s1, REG_ATMP1);
1423 M_AADDINT(REG_ITMP2, REG_ATMP1);
1424 /* implicit null-pointer check */
1425 #if !defined(ENABLE_SOFTFLOAT)
1426 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1427 M_FLD(d, REG_ATMP1, 0);
1429 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1430 M_LWZX(REG_ATMP1, d);
1432 emit_store_dst(jd, iptr, d);
1435 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1436 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1437 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1438 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1439 M_INTMOVE(s2, REG_ITMP2);
1440 M_ISSL_IMM(3, REG_ITMP2);
1441 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1442 M_ADRMOVE(s1, REG_ATMP1);
1443 M_AADDINT(REG_ITMP2, REG_ATMP1);
1444 /* implicit null-pointer check */
1445 #if !defined(ENABLE_SOFTFLOAT)
1446 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1447 M_DLD(d, REG_ATMP1, 0);
1449 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1450 M_LLD(d, REG_ATMP1, 0);
1452 emit_store_dst(jd, iptr, d);
1455 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1456 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1457 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1458 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1459 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1460 M_INTMOVE(s2, REG_ITMP2);
1461 M_ISSL_IMM(2, REG_ITMP2);
1462 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1463 M_ADRMOVE(s1, REG_ATMP1);
1464 M_AADDINT(REG_ITMP2, REG_ATMP1);
1466 /* implicit null-pointer check */
1467 M_LAX(REG_ATMP1, d);
1468 emit_store_dst(jd, iptr, d);
1472 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1473 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1474 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1475 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1476 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1477 M_INTMOVE(s2, REG_ITMP2);
1478 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1479 M_ADRMOVE(s1, REG_ATMP1);
1480 M_AADDINT(REG_ITMP2, REG_ATMP1);
1481 /* implicit null-pointer check */
1482 M_STBX(REG_ATMP1, s3);
1485 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1486 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1487 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1488 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1489 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1490 M_INTMOVE(s2, REG_ITMP2);
1491 M_ISSL_IMM(1, REG_ITMP2);
1492 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1493 M_ADRMOVE(s1, REG_ATMP1);
1494 M_AADDINT(REG_ITMP2, REG_ATMP1);
1495 /* implicit null-pointer check */
1496 M_STHX(REG_ATMP1, s3);
1499 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1500 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1501 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1502 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1503 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1504 M_INTMOVE(s2, REG_ITMP2);
1505 M_ISSL_IMM(1, REG_ITMP2);
1506 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1507 M_ADRMOVE(s1, REG_ATMP1);
1508 M_AADDINT(REG_ITMP2, REG_ATMP1);
1509 /* implicit null-pointer check */
1510 M_STHX(REG_ATMP1, s3);
1513 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1515 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1516 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1517 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1518 M_INTMOVE(s2, REG_ITMP2);
1519 M_ISSL_IMM(2, REG_ITMP2);
1520 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1521 M_ADRMOVE(s1, REG_ATMP1);
1522 M_AADDINT(REG_ITMP2, REG_ATMP1);
1523 /* implicit null-pointer check */
1524 M_STWX(REG_ATMP1, s3);
1527 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1528 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1529 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1530 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1532 M_INTMOVE(s2, REG_ITMP1);
1533 M_ISSL_IMM(3, REG_ITMP1);
1534 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1535 M_ADRMOVE(s1, REG_ATMP1);
1536 M_AADDINT(REG_ITMP1, REG_ATMP1);
1537 /* implicit null-pointer check */
1538 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1539 M_LST(s3, REG_ATMP1, 0);
1542 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1544 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1545 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1546 M_INTMOVE(s2, REG_ITMP2);
1547 M_ISSL_IMM(2, REG_ITMP2);
1548 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1549 M_ADRMOVE(s1, REG_ATMP1);
1550 M_AADDINT(REG_ITMP2, REG_ATMP1);
1551 /* implicit null-pointer check */
1552 #if !defined(ENABLE_SOFTFLOAT)
1553 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1554 M_FST(s3, REG_ATMP1, 0);
1556 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1557 M_STWX(REG_ATMP1, s3);
1561 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1563 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1564 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1565 M_INTMOVE(s2, REG_ITMP2);
1566 M_ISSL_IMM(3, REG_ITMP2);
1567 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1568 M_ADRMOVE(s1, REG_ATMP1);
1569 M_AADDINT(REG_ITMP2, REG_ATMP1);
1570 /* implicit null-pointer check */
1571 #if !defined(ENABLE_SOFTFLOAT)
1572 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1573 M_DST(s3, REG_ATMP1, 0);
1575 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1576 /* implicit null-pointer check */
1577 M_LST(s3, REG_ATMP1, 0);
1581 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1583 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1584 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1585 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1586 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1588 /* XXX what if array is NULL */
1589 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1591 M_AST(s1, REG_SP, 0*4);
1592 M_AST(s3, REG_SP, 1*4);
1593 M_JSR_IMM(BUILTIN_FAST_canstore);
1594 emit_arraystore_check(cd, iptr);
1596 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1597 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1598 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1599 M_INTMOVE(s2, REG_ITMP1);
1600 M_ISSL_IMM(2, REG_ITMP1);
1601 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1602 M_ADRMOVE(s1, REG_ATMP1);
1603 M_AADDINT(REG_ITMP1, REG_ATMP1);
1604 /* implicit null-pointer check */
1605 M_STAX(REG_ATMP1, s3);
1610 /* METHOD INVOCATION *********************************************************/
1611 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1612 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1614 bte = iptr->sx.s23.s3.bte;
1618 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1619 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1620 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1621 case ICMD_INVOKEINTERFACE:
1622 REPLACEMENT_POINT_INVOKE(cd, iptr);
1624 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1626 um = iptr->sx.s23.s3.um;
1627 md = um->methodref->parseddesc.md;
1630 lm = iptr->sx.s23.s3.fmiref->p.method;
1632 md = lm->parseddesc;
1635 s3 = md->paramcount;
1637 MCODECHECK((s3 << 1) + 64);
1639 /* copy arguments to stack */
1640 for (s3 = s3 - 1; s3 >= 0; s3--) {
1641 var = VAR(iptr->sx.s23.s2.args[s3]);
1642 /* already preallocated */
1643 if (var->flags & PREALLOC) continue;
1645 if (!md->params[s3].inmemory) assert(0);
1647 switch (var->type) {
1648 #if defined(ENABLE_SOFTFLOAT)
1652 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1653 M_LST(d, REG_SP, md->params[s3].regoff);
1655 #if defined(ENABLE_SOFTFLOAT)
1659 d = emit_load(jd, iptr, var, REG_ITMP1);
1660 M_IST(d, REG_SP, md->params[s3].regoff);
1663 d = emit_load(jd, iptr, var, REG_ATMP1);
1664 M_AST(d, REG_SP, md->params[s3].regoff);
1666 #if !defined(ENABLE_SOFTFLOAT)
1668 d = emit_load(jd, iptr, var, REG_FTMP1);
1669 M_FST(d, REG_SP, md->params[s3].regoff);
1672 d = emit_load(jd, iptr, var, REG_FTMP1);
1673 M_DST(d, REG_SP, md->params[s3].regoff);
1681 /* arguments in place now */
1684 if (bte->stub == NULL)
1685 disp = (ptrint) bte->fp;
1687 disp = (ptrint) bte->stub;
1688 d = md->returntype.type;
1691 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1694 case ICMD_INVOKESPECIAL:
1695 /* adress register for sure */
1696 M_ALD(REG_ATMP1, REG_SP, 0);
1697 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1699 case ICMD_INVOKESTATIC:
1701 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1703 M_AMOV_IMM(disp, REG_ATMP1);
1705 disp = lm->stubroutine;
1706 M_AMOV_IMM(disp, REG_ATMP1);
1709 /* generate the actual call */
1711 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1715 case ICMD_INVOKEVIRTUAL:
1717 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1720 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1722 /* load object pointer (==argument 0) */
1723 M_ALD(REG_ATMP1, REG_SP, 0);
1724 /* implicit null-pointer check */
1725 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1726 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1727 /* generate the actual call */
1730 case ICMD_INVOKEINTERFACE:
1732 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1737 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1738 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1740 /* load object pointer (==argument 0) */
1741 M_ALD(REG_ATMP1, REG_SP, 0);
1743 /* implicit null-pointer check */
1744 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1745 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1746 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1748 /* generate the actual call */
1750 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1754 } /* switch (iptr->opc) */
1756 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1757 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1759 /* store return value */
1760 d = md->returntype.type;
1763 case TYPE_VOID: break;
1764 #if defined(ENABLE_SOFTFLOAT)
1768 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1769 M_INTMOVE(REG_RESULT, s1);
1771 #if defined(ENABLE_SOFTFLOAT)
1775 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1776 M_LNGMOVE(REG_RESULT_PACKED, s1);
1779 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1780 /* all stuff is returned in %d0 */
1781 M_INT2ADRMOVE(REG_RESULT, s1);
1783 #if !defined(ENABLE_SOFTFLOAT)
1785 * for BUILTINS float values are returned in %d0,%d1
1786 * within cacao we use %fp0 for that.
1789 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1790 if (iptr->opc == ICMD_BUILTIN) {
1791 M_INT2FLTMOVE(REG_FRESULT, s1);
1793 M_FLTMOVE(REG_FRESULT, s1);
1797 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1798 if (iptr->opc == ICMD_BUILTIN) {
1799 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1800 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1802 M_DBLMOVE(REG_FRESULT, s1);
1809 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1810 break; /* ICMD_INVOKE* */
1812 #if defined(ENABLE_SOFTFLOAT)
1815 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1817 REPLACEMENT_POINT_RETURN(cd, iptr);
1818 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1819 M_INTMOVE(s1, REG_RESULT);
1820 goto nowperformreturn;
1822 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1824 REPLACEMENT_POINT_RETURN(cd, iptr);
1825 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1826 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1827 M_ADR2INTMOVE(s1, REG_RESULT);
1829 #ifdef ENABLE_VERIFIER
1830 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1831 unresolved_class *uc = iptr->sx.s23.s2.uc;
1833 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
1835 #endif /* ENABLE_VERIFIER */
1836 goto nowperformreturn;
1838 #if defined(ENABLE_SOFTFLOAT)
1841 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1842 REPLACEMENT_POINT_RETURN(cd, iptr);
1843 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1844 M_LNGMOVE(s1, REG_RESULT_PACKED);
1845 goto nowperformreturn;
1847 #if !defined(ENABLE_SOFTFLOAT)
1848 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1849 REPLACEMENT_POINT_RETURN(cd, iptr);
1850 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1851 M_FLTMOVE(s1, REG_FRESULT);
1852 goto nowperformreturn;
1855 REPLACEMENT_POINT_RETURN(cd, iptr);
1856 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1857 M_DBLMOVE(s1, REG_FRESULT);
1858 goto nowperformreturn;
1862 case ICMD_RETURN: /* ... ==> ... */
1864 REPLACEMENT_POINT_RETURN(cd, iptr);
1870 p = cd->stackframesize;
1872 /* call trace function */
1873 #if !defined(NDEBUG)
1874 emit_verbosecall_exit(jd);
1877 #if defined(ENABLE_THREADS)
1878 /* call lock_monitor_exit */
1879 if (checksync && code_is_synchronized(code)) {
1880 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1882 /* we need to save the proper return value */
1883 /* we do not care for the long -> doubel convert space here */
1884 switch (iptr->opc) {
1885 #if defined(ENABLE_SOFTFLOAT)
1889 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1891 #if defined(ENABLE_SOFTFLOAT)
1896 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1898 #if !defined(ENABLE_SOFTFLOAT)
1900 M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1903 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1908 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1909 M_JSR_IMM(LOCK_monitor_exit);
1911 /* and now restore the proper return value */
1912 switch (iptr->opc) {
1914 #if defined(ENABLE_SOFTFLOAT)
1918 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1920 #if defined(ENABLE_SOFTFLOAT)
1925 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1927 #if !defined(ENABLE_SOFTFLOAT)
1929 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1932 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1940 /* restore return address */
1942 if (!code_is_leafmethod(code)) {
1943 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1944 may have a displacement overflow. */
1946 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1950 /* restore saved registers */
1952 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1953 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1955 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1956 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1958 #if !defined(ENABLE_SOFTFLOAT)
1959 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1960 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1963 /* deallocate stack */
1964 M_AADD_IMM(cd->stackframesize, REG_SP);
1970 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1971 /* val.a: (classinfo*) superclass */
1973 /* superclass is an interface:
1975 * return (sub != NULL) &&
1976 * (sub->vftbl->interfacetablelength > super->index) &&
1977 * (sub->vftbl->interfacetable[-super->index] != NULL);
1979 * superclass is a class:
1981 * return ((sub != NULL) && (0
1982 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1983 * super->vftbl->diffvall));
1990 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1995 super = iptr->sx.s23.s3.c.cls;
1996 superindex = super->index;
1999 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2000 CODEGEN_CRITICAL_SECTION_NEW;
2002 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2003 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2005 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2006 assert(VAROP(iptr->dst)->type == TYPE_INT);
2010 /* if class is not resolved, check which code to call */
2012 if (super == NULL) {
2014 emit_label_beq(cd, BRANCH_LABEL_1);
2016 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2018 M_IMOV_IMM32(0, REG_ITMP3);
2019 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2020 emit_label_beq(cd, BRANCH_LABEL_2);
2023 /* interface instanceof code */
2025 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2026 if (super == NULL) {
2027 patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2030 emit_label_beq(cd, BRANCH_LABEL_3);
2033 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2034 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2035 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
2038 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
2044 emit_label_br(cd, BRANCH_LABEL_4);
2046 emit_label(cd, BRANCH_LABEL_3);
2049 /* class instanceof code */
2051 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2052 if (super == NULL) {
2053 emit_label(cd, BRANCH_LABEL_2);
2055 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2056 M_AMOV_IMM(0, REG_ATMP2);
2058 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2060 emit_label_beq(cd, BRANCH_LABEL_5);
2063 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2065 CODEGEN_CRITICAL_SECTION_START;
2067 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2068 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2069 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2071 CODEGEN_CRITICAL_SECTION_END;
2073 M_ISUB(REG_ITMP3, REG_ITMP1);
2074 M_ICMP(REG_ITMP2, REG_ITMP1);
2077 M_TPFW; /* overlaps next instruction */
2081 emit_label(cd, BRANCH_LABEL_5);
2084 if (super == NULL) {
2085 emit_label(cd, BRANCH_LABEL_1);
2086 emit_label(cd, BRANCH_LABEL_4);
2089 emit_store_dst(jd, iptr, d);
2093 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2094 /* val.a: (classinfo*) superclass */
2096 /* superclass is an interface:
2098 * OK if ((sub == NULL) ||
2099 * (sub->vftbl->interfacetablelength > super->index) &&
2100 * (sub->vftbl->interfacetable[-super->index] != NULL));
2102 * superclass is a class:
2104 * OK if ((sub == NULL) || (0
2105 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2106 * super->vftbl->diffvall));
2109 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2110 /* object type cast-check */
2115 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2120 super = iptr->sx.s23.s3.c.cls;
2121 superindex = super->index;
2124 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2125 CODEGEN_CRITICAL_SECTION_NEW;
2127 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2128 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2130 /* if class is not resolved, check which code to call */
2132 if (super == NULL) {
2134 emit_label_beq(cd, BRANCH_LABEL_1);
2136 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2138 M_IMOV_IMM32(0, REG_ITMP2);
2139 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2140 emit_label_beq(cd, BRANCH_LABEL_2);
2143 /* interface checkcast code */
2145 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2146 if (super == NULL) {
2147 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2150 emit_label_beq(cd, BRANCH_LABEL_3);
2153 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2154 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2156 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2158 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2160 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2162 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2165 emit_label_br(cd, BRANCH_LABEL_4);
2167 emit_label(cd, BRANCH_LABEL_3);
2170 /* class checkcast code */
2172 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2173 if (super == NULL) {
2174 emit_label(cd, BRANCH_LABEL_2);
2176 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2177 M_AMOV_IMM(0, REG_ATMP3);
2179 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2181 emit_label_beq(cd, BRANCH_LABEL_5);
2184 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2186 CODEGEN_CRITICAL_SECTION_START;
2188 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2189 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2190 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2192 CODEGEN_CRITICAL_SECTION_END;
2194 M_ISUB(REG_ITMP1, REG_ITMP3);
2195 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2197 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2200 emit_label(cd, BRANCH_LABEL_5);
2203 if (super == NULL) {
2204 emit_label(cd, BRANCH_LABEL_1);
2205 emit_label(cd, BRANCH_LABEL_4);
2208 d = codegen_reg_of_dst(jd, iptr, s1);
2210 /* array type cast-check */
2212 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2214 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2215 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2216 M_AMOV_IMM(0, REG_ATMP1);
2218 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2223 M_JSR_IMM(BUILTIN_arraycheckcast);
2224 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2226 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2228 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2229 d = codegen_reg_of_dst(jd, iptr, s1);
2231 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2233 emit_store_dst(jd, iptr, d);
2236 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2239 branch_target_t *table;
2241 table = iptr->dst.table;
2243 l = iptr->sx.s23.s2.tablelow;
2244 i = iptr->sx.s23.s3.tablehigh;
2246 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2247 M_INTMOVE(s1, REG_ITMP1);
2248 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2253 M_ICMP_IMM(i - 1, REG_ITMP1);
2254 emit_bugt(cd, table[0].block);
2256 /* build jump table top down and use address of lowest entry */
2260 dseg_add_target(cd, table->block);
2264 /* length of dataseg after last dseg_add_target is used by load */
2265 M_AMOV_IMM(0, REG_ATMP2);
2268 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2269 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2270 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2271 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2278 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2281 lookup_target_t *lookup;
2283 lookup = iptr->dst.lookup;
2285 i = iptr->sx.s23.s2.lookupcount;
2287 MCODECHECK((i<<2)+8);
2288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2291 M_ICMP_IMM(lookup->value, s1);
2292 emit_beq(cd, lookup->target.block);
2296 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2301 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2303 /* check for negative sizes and copy sizes to stack if necessary */
2304 MCODECHECK((iptr->s1.argcount << 1) + 64);
2306 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2307 var = VAR(iptr->sx.s23.s2.args[s1]);
2309 /* Already Preallocated? */
2310 if (!(var->flags & PREALLOC)) {
2311 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2312 M_IST(s2, REG_SP, (s1 + 3) * 4);
2316 /* a0 = dimension count */
2317 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2318 M_IST(REG_ITMP1, REG_SP, 0*4);
2320 /* a1 = arraydescriptor */
2321 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2322 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2323 M_AMOV_IMM(0, REG_ATMP1);
2325 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2327 M_AST(REG_ATMP1, REG_SP, 1*4);
2329 /* a2 = pointer to dimensions = stack pointer */
2330 M_AMOV(REG_SP, REG_ATMP1);
2331 M_AADD_IMM(3*4, REG_ATMP1);
2332 M_AST(REG_ATMP1, REG_SP, 2*4);
2334 M_JSR_IMM(BUILTIN_multianewarray);
2336 /* check for exception before result assignment */
2337 emit_exception_check(cd, iptr);
2339 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2340 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2341 M_INT2ADRMOVE(REG_RESULT, d);
2342 emit_store_dst(jd, iptr, d);
2348 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2349 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2352 /* M_TPF; */ /* nop after each ICMD */
2353 } /* for each instruction */
2355 /* At the end of a basic block we may have to append some nops,
2356 because the patcher stub calling code might be longer than the
2357 actual instruction. So codepatching does not change the
2358 following block unintentionally. */
2360 if (cd->mcodeptr < cd->lastmcodeptr) {
2361 while (cd->mcodeptr < cd->lastmcodeptr) {
2367 } /* if (btpre->flags >= BBREACHED) */
2368 } /* for each basic block */
2370 /* generate stubs */
2371 emit_patcher_traps(jd);
2376 /* codegen_emit_stub_native ****************************************************
2378 Emits a stub routine which calls a native method.
2380 *******************************************************************************/
2382 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2391 /* get required compiler data */
2400 /* calc stackframe size */
2401 cd->stackframesize =
2402 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2403 sizeof(localref_table) / SIZEOF_VOID_P +
2405 1 + /* functionptr */
2406 4; /* args for codegen_start_native_call */
2408 /* create method header */
2409 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2410 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2411 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2412 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2413 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2415 /* print call trace */
2416 #if !defined(NDEBUG)
2417 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2418 emit_verbosecall_enter(jd);
2423 M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
2425 /* get function address (this must happen before the stackframeinfo) */
2427 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, 0);
2430 M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2432 M_AST(REG_ATMP2, REG_SP, 4 * 4);
2434 /* put arguments for codegen_start_native_call onto stack */
2435 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2437 M_AMOV(REG_SP, REG_ATMP1);
2438 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2440 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2441 dseg_adddata(cd); /* this patches it */
2443 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2445 M_JSR_IMM(codegen_start_native_call);
2447 /* remember class argument */
2448 if (m->flags & ACC_STATIC)
2449 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2451 /* load function pointer */
2452 M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2454 /* copy arguments into stackframe */
2455 for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) {
2456 t = md->paramtypes[i].type;
2457 /* all arguments via stack */
2458 assert(md->params[i].inmemory);
2460 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
2461 s2 = nmd->params[j].regoff;
2463 /* simply copy argument stack */
2464 M_ILD(REG_ITMP1, REG_SP, s1);
2465 M_IST(REG_ITMP1, REG_SP, s2);
2466 if (IS_2_WORD_TYPE(t)) {
2467 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2468 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2472 /* for static function class as second arg */
2473 if (m->flags & ACC_STATIC)
2474 M_AST(REG_ATMP3, REG_SP, 1 * 4);
2476 /* env ist first argument */
2477 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2478 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2480 /* call the native function */
2483 /* save return value */
2484 switch (md->returntype.type) {
2485 case TYPE_VOID: break;
2487 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2490 M_IST(REG_D1, REG_SP, 2 * 8);
2496 M_IST(REG_D0, REG_SP, 2 * 8); /* XXX can this be correct ? */
2502 /* print call trace */
2503 #if ! defined(NDEBUG)
2504 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2505 emit_verbosecall_exit(jd);
2508 /* remove native stackframe info */
2509 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2511 M_AMOV(REG_SP, REG_ATMP1);
2512 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2514 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2515 dseg_adddata(cd); /* this patches it */
2517 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2519 M_JSR_IMM(codegen_finish_native_call);
2521 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2522 /* restore return value */
2523 switch (md->returntype.type) {
2524 case TYPE_VOID: break;
2527 case TYPE_LNG: M_ILD(REG_D1, REG_SP, 2 * 8);
2532 M_ILD(REG_D0, REG_SP, 2 * 8); /* XXX */
2537 #if !defined(ENABLE_SOFTFLOAT)
2538 /* additionally load values into floating points registers
2539 * as cacao jit code expects them there */
2540 switch (md->returntype.type) {
2542 M_FLD(REG_D0, REG_SP, 2 * 8);
2545 M_DLD(REG_D0, REG_SP, 2 * 8); /* XXX */
2549 /* restore saved registers */
2551 M_AADD_IMM(cd->stackframesize*8, REG_SP);
2552 /* check for exception */
2557 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2559 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2560 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2561 M_JMP_IMM(asm_handle_nat_exception);
2563 /* should never be reached from within jit code*/
2566 /* generate patcher stub call code */
2567 emit_patcher_traps(jd);
2572 * These are local overrides for various environment variables in Emacs.
2573 * Please do not remove this and leave it at the end of the file, where
2574 * Emacs will automagically detect them.
2575 * ---------------------------------------------------------------------
2578 * indent-tabs-mode: t
2582 * vim:noexpandtab:sw=4:ts=4: