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
25 $Id: codegen.c 7564 2007-03-23 23:36:17Z twisti $
38 #include "vm/jit/m68k/codegen.h"
39 #include "vm/jit/m68k/emit.h"
41 #include "mm/memory.h"
42 #include "native/jni.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/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/abi.h"
59 #include "vm/jit/parse.h"
60 #include "vm/jit/patcher.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
63 #include "vm/jit/stacktrace.h"
64 #include "vm/jit/md.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;
84 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
85 unresolved_method *um;
86 builtintable_entry *bte;
93 /* get required compiler data */
100 /* prevent compiler warnings */
108 /* save calle saved registers */
109 s4 savedregs_num = 0;
111 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
112 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
113 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
115 cd->stackframesize = rd->memuse + savedregs_num;
117 /* we always add 2 stack slots.
118 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
119 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
120 * on the other hand we could use 2 words when a builtin returns a doulbe which are
121 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
122 * so we always _need_ at least 2 slots, and this keeps the code simple */
123 cd->stackframesize += 2;
125 cd->stackframesize *= 8; /* we use 8 byte stack slots */
128 #if defined(ENABLE_THREADS)
129 /* we need additional space to save argument of monitor_enter */
130 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
131 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
132 cd->stackframesize += 2;
134 cd->stackframesize += 1;
140 /* create method header */
141 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
142 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
143 #if defined(ENABLE_THREADS)
144 if (checksync && (m->flags & ACC_SYNCHRONIZED))
145 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8);/* IsSync */
148 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
149 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
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 dseg_addlinenumbertablesize(cd);
157 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
159 /* create exception table */
160 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
161 dseg_add_target(cd, ex->start);
162 dseg_add_target(cd, ex->end);
163 dseg_add_target(cd, ex->handler);
164 (void) dseg_add_unique_address(cd, ex->catchtype.any);
167 #if defined(ENABLE_PROFILING)
172 emit_verbosecall_enter(jd);
174 /* create stack frame */
175 M_AADD_IMM(-(cd->stackframesize), REG_SP);
177 /* save used callee saved registers */
178 p = cd->stackframesize;
179 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
180 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
182 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
183 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
185 #if !defined(ENABLE_SOFTFLOAT)
186 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
187 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
190 assert(FLT_SAV_CNT == 0);
191 assert(rd->savfltreguse == 0);
193 /* take arguments out of stack frame */
195 for (p = 0, l = 0; p < md->paramcount; p++) {
196 t = md->paramtypes[p].type;
197 varindex = jd->local_map[l * 5 + t];
200 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
203 if (varindex == UNUSED)
208 s1 = md->params[p].regoff;
209 assert(md->params[p].inmemory); /* all args are on stack */
212 #if defined(ENABLE_SOFTFLOAT)
218 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
219 if (IS_2_WORD_TYPE(t)) {
220 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
222 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
224 } else { /* stack arg -> spilled */
225 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
226 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
227 if (IS_2_WORD_TYPE(t)) {
228 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
229 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
233 #if !defined(ENABLE_SOFTFLOAT)
236 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
237 if (IS_2_WORD_TYPE(t)) {
238 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
240 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
242 } else { /* stack-arg -> spilled */
243 if (IS_2_WORD_TYPE(t)) {
244 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
245 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
247 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
248 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
252 #endif /* SOFTFLOAT */
254 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
255 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
256 } else { /* stack-arg -> spilled */
257 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
258 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
263 } /* end for argument out of stack*/
265 #if defined(ENABLE_THREADS)
266 /* call lock_monitor_enter function */
267 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
268 if (m->flags & ACC_STATIC) {
269 M_AMOV_IMM((&m->class->object.header), REG_ATMP1);
271 /* for non-static case the first arg is the object */
272 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
275 M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
278 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
279 M_AST(REG_ATMP1, REG_SP, 0 * 4);
280 M_JSR_IMM(LOCK_monitor_enter);
286 /* create replacement points */
287 REPLACEMENT_POINTS_INIT(cd, jd);
289 /* foreach basic block */
290 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
292 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
294 if (bptr->flags >= BBREACHED) {
296 /* branch resolving */
297 codegen_resolve_branchrefs(cd, bptr);
299 /* handle replacement points */
300 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
302 #if defined(ENABLE_PROFILING)
305 /* FIXME there are still some constrcuts to copy in here */
307 #if defined(ENABLE_LSRA)
311 /* copy interface registers to their destination */
317 var = VAR(bptr->invars[len]);
318 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
319 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
320 M_ADRMOVE(REG_ATMP1_XPTR, d);
321 emit_store(jd, NULL, var, d);
324 assert((var->flags & INOUT));
328 /* walk through all instructions */
332 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
333 if (iptr->line != currentline) {
334 dseg_addlinenumber(cd, iptr->line);
335 currentline = iptr->line;
338 MCODECHECK(1024); /* 1kB should be enough */
341 case ICMD_NOP: /* ... ==> ... */
342 case ICMD_POP: /* ..., value ==> ... */
343 case ICMD_POP2: /* ..., value, value ==> ... */
346 case ICMD_INLINE_START:
348 REPLACEMENT_POINT_INLINE_START(cd, iptr);
351 case ICMD_INLINE_BODY:
353 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
354 dseg_addlinenumber_inline_start(cd, iptr);
355 dseg_addlinenumber(cd, iptr->line);
358 case ICMD_INLINE_END:
360 dseg_addlinenumber_inline_end(cd, iptr);
361 dseg_addlinenumber(cd, iptr->line);
364 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
367 assert(VAROP(iptr->s1)->type == TYPE_ADR);
368 emit_nullpointer_check(cd, iptr, s1);
372 /* CONST **************************************************************/
373 case ICMD_ICONST: /* ... ==> ..., constant */
374 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
375 M_IMOV_IMM(iptr->sx.val.i, d);
376 emit_store_dst(jd, iptr, d);
379 case ICMD_LCONST: /* ... ==> ..., constant */
381 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
382 LCONST(iptr->sx.val.l, d);
383 emit_store_dst(jd, iptr, d);
386 case ICMD_FCONST: /* ... ==> ..., constant */
388 #if defined(ENABLE_SOFTFLOAT)
389 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
390 M_IMOV_IMM(iptr->sx.val.i, d);
391 emit_store_dst(jd, iptr, d);
393 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
394 FCONST(iptr->sx.val.i, d);
395 emit_store_dst(jd, iptr, d);
399 case ICMD_DCONST: /* ... ==> ..., constant */
401 #if defined(ENABLE_SOFTFLOAT)
402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
403 LCONST(iptr->sx.val.l, d);
404 emit_store_dst(jd, iptr, d);
406 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
407 disp = dseg_add_double(cd, iptr->sx.val.d);
408 M_AMOV_IMM(0, REG_ATMP1);
410 M_DLD(d, REG_ATMP1, disp);
411 emit_store_dst(jd, iptr, d);
416 /* some long operations *********************************************/
417 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
418 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
419 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
420 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
421 M_INTMOVE(s2, REG_ITMP1);
422 M_IADD(s1, REG_ITMP1); /* low word */
423 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
424 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
425 M_INTMOVE(s2, REG_ITMP2);
426 M_IADDX(s1, REG_ITMP2); /* high word */
427 emit_store_dst(jd, iptr, d);
430 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
431 /* sx.val.l = constant */
432 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
433 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
436 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
438 s3 = iptr->sx.val.l & 0xffffffff;
439 M_INTMOVE(s1, REG_ITMP1);
440 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
442 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
443 M_LNGMOVE(REG_ITMP12_PACKED, d);
444 emit_store_dst(jd, iptr, d);
447 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
448 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
449 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
450 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
451 M_INTMOVE(s1, REG_ITMP1);
452 M_ISUB(s2, REG_ITMP1); /* low word */
453 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
454 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
455 M_INTMOVE(s1, REG_ITMP2);
456 M_ISUBX(s2, REG_ITMP2); /* high word */
457 emit_store_dst(jd, iptr, d);
460 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
461 /* sx.val.l = constant */
462 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
463 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
466 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
468 s3 = (-iptr->sx.val.l) & 0xffffffff;
469 M_INTMOVE(s1, REG_ITMP1);
470 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
472 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
473 M_LNGMOVE(REG_ITMP12_PACKED, d);
474 emit_store_dst(jd, iptr, d);
477 case ICMD_LNEG: /* ..., value ==> ..., - value */
478 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
479 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
480 M_LNGMOVE(s1, REG_ITMP12_PACKED);
481 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
482 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
483 M_LNGMOVE(REG_ITMP12_PACKED, d);
484 emit_store_dst(jd, iptr, d);
487 /* integer operations ************************************************/
488 case ICMD_INEG: /* ..., value ==> ..., - value */
490 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
491 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
492 M_INTMOVE(s1, REG_ITMP1);
494 M_INTMOVE(REG_ITMP1, d);
495 emit_store_dst(jd, iptr, d);
498 case ICMD_I2L: /* ..., value ==> ..., value */
500 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
502 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
504 M_ISET(GET_HIGH_REG(d));
506 M_ICLR(GET_HIGH_REG(d));
508 emit_store_dst(jd, iptr, d);
511 case ICMD_L2I: /* ..., value ==> ..., value */
513 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
514 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
516 emit_store_dst(jd, iptr, d);
518 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
523 emit_store_dst(jd, iptr, d);
526 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
528 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
529 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
531 emit_store_dst(jd, iptr, d);
534 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
536 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
539 emit_store_dst(jd, iptr, d);
544 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
549 M_INTMOVE(s2, REG_ITMP2);
550 M_IADD(s1, REG_ITMP2);
551 M_INTMOVE(REG_ITMP2, d);
552 emit_store_dst(jd, iptr, d);
555 /* s1.localindex = variable, sx.val.i = constant*/
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
562 M_INTMOVE(s1, REG_ITMP1);
563 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
564 M_INTMOVE(REG_ITMP1, d);
565 emit_store_dst(jd, iptr, d);
568 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
570 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
571 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
573 M_INTMOVE(s1, REG_ITMP1);
574 M_ISUB(s2, REG_ITMP1);
575 M_INTMOVE(REG_ITMP1, d);
576 emit_store_dst(jd, iptr, d);
579 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
580 /* sx.val.i = constant */
582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
584 M_INTMOVE(s1, REG_ITMP1);
585 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
586 M_INTMOVE(REG_ITMP1, d);
587 emit_store_dst(jd, iptr, d);
590 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
592 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
594 emit_arithmetic_check(cd, iptr, s2);
595 M_INTMOVE(s1, REG_ITMP1);
596 M_IDIV(s2, REG_ITMP1);
597 M_INTMOVE(REG_ITMP1, d);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
603 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
604 M_INTMOVE(s1, REG_ITMP1);
608 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
610 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
611 M_ISSR(REG_ITMP2, REG_ITMP1);
612 M_INTMOVE(REG_ITMP1, d);
613 emit_store_dst(jd, iptr, d);
616 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
618 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
620 emit_arithmetic_check(cd, iptr, s2);
622 M_ICMP_IMM(0x80000000, s1);
627 M_TPFL; /* hides the next instruction */
628 M_IREM(s2, s1, REG_ITMP3);
630 M_INTMOVE(REG_ITMP3, d);
632 emit_store_dst(jd, iptr, d);
635 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
639 M_IMOV(s1, REG_ITMP1);
643 M_IAND_IMM(iptr->sx.val.i, d);
645 M_BGE(2 + 2 + 6 + 2);
646 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
648 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
651 emit_store_dst(jd, iptr, d);
655 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
656 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
658 bte = iptr->sx.s23.s3.bte;
661 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
662 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
663 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
664 /* XXX could be optimized */
665 emit_arithmetic_check(cd, iptr, REG_ITMP3);
667 M_LST(s2, REG_SP, 2 * 4);
668 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
669 M_LST(s1, REG_SP, 0 * 4);
673 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
674 M_LNGMOVE(REG_RESULT_PACKED, d);
675 emit_store_dst(jd, iptr, d);
678 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
680 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
681 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
682 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
683 M_INTMOVE(s2, REG_ITMP2);
684 M_IMUL(s1, REG_ITMP2);
685 M_INTMOVE(REG_ITMP2, d);
686 emit_store_dst(jd, iptr, d);
689 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
690 /* sx.val.i = constant */
691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
693 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
694 M_IMUL(s1, REG_ITMP2);
695 M_INTMOVE(REG_ITMP2, d);
696 emit_store_dst(jd, iptr, d);
699 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
702 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
703 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
704 M_INTMOVE(s1, REG_ITMP1);
705 M_INTMOVE(s2, REG_ITMP2);
706 M_IAND_IMM(0x1f, REG_ITMP2);
707 M_ISSL(REG_ITMP2, REG_ITMP1);
708 M_INTMOVE(REG_ITMP1, d);
709 emit_store_dst(jd, iptr, d);
712 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
713 /* sx.val.i = constant */
715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
716 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
717 if (iptr->sx.val.i & 0x1f) {
718 M_INTMOVE(s1, REG_ITMP1)
719 if ((iptr->sx.val.i & 0x1f) <= 7) {
720 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
722 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
723 M_ISSL(REG_ITMP2, REG_ITMP1);
725 M_INTMOVE(REG_ITMP1, d);
729 emit_store_dst(jd, iptr, d);
732 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
737 M_INTMOVE(s1, REG_ITMP1);
738 M_INTMOVE(s2, REG_ITMP2);
739 M_IAND_IMM(0x1f, REG_ITMP2);
740 M_ISSR(REG_ITMP2, REG_ITMP1);
741 M_INTMOVE(REG_ITMP1, d);
742 emit_store_dst(jd, iptr, d);
745 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
746 /* sx.val.i = constant */
748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
749 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
750 if (iptr->sx.val.i & 0x1f) {
751 M_INTMOVE(s1, REG_ITMP1)
752 if ((iptr->sx.val.i & 0x1f) <= 7) {
753 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
755 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
756 M_ISSR(REG_ITMP2, REG_ITMP1);
758 M_INTMOVE(REG_ITMP1, d);
762 emit_store_dst(jd, iptr, d);
765 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
767 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
768 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
769 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
770 M_INTMOVE(s1, REG_ITMP1);
771 M_INTMOVE(s2, REG_ITMP2);
772 M_IAND_IMM(0x1f, REG_ITMP2);
773 M_IUSR(REG_ITMP2, REG_ITMP1);
774 M_INTMOVE(REG_ITMP1, d);
775 emit_store_dst(jd, iptr, d);
778 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
779 /* sx.val.i = constant */
780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
782 if (iptr->sx.val.i & 0x1f) {
783 M_INTMOVE(s1, REG_ITMP1)
784 if ((iptr->sx.val.i & 0x1f) <= 7) {
785 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
787 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
788 M_IUSR(REG_ITMP2, REG_ITMP1);
790 M_INTMOVE(REG_ITMP1, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
800 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 M_INTMOVE(s2, REG_ITMP2);
803 M_IAND(s1, REG_ITMP2);
804 M_INTMOVE(REG_ITMP2, d);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
809 /* sx.val.i = constant */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
813 M_INTMOVE(s1, REG_ITMP1);
814 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
815 M_INTMOVE(REG_ITMP1, d);
816 emit_store_dst(jd, iptr, d);
819 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
823 M_INTMOVE(s2, REG_ITMP2);
824 M_IOR(s1, REG_ITMP2);
825 M_INTMOVE(REG_ITMP2, d);
826 emit_store_dst(jd, iptr, d);
829 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
830 /* sx.val.i = constant */
831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
833 M_INTMOVE(s1, REG_ITMP1);
834 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
835 M_INTMOVE(REG_ITMP1, d);
836 emit_store_dst(jd, iptr, d);
839 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 M_INTMOVE(s2, REG_ITMP2);
844 M_IXOR(s1, REG_ITMP2);
845 M_INTMOVE(REG_ITMP2, d);
846 emit_store_dst(jd, iptr, d);
849 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
850 /* sx.val.i = constant */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
853 M_INTMOVE(s1, REG_ITMP1);
854 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
855 M_INTMOVE(REG_ITMP1, d);
856 emit_store_dst(jd, iptr, d);
859 /* floating point operations ******************************************/
860 #if !defined(ENABLE_SOFTFLOAT)
861 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
863 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
864 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
865 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
868 M_BFUN(14); /* result is -1, branch to end */
869 M_BFLT(10); /* result is -1, branch to end */
871 M_BFEQ(4) /* result is 0, branch to end */
873 emit_store_dst(jd, iptr, d);
876 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
878 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
879 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
880 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
883 M_BFUN(16); /* result is +1, branch to end */
884 M_BFGT(14); /* result is +1, branch to end */
886 M_BFEQ(8) /* result is 0, branch to end */
888 emit_store_dst(jd, iptr, d);
891 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
892 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
893 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
894 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
895 M_FLTMOVE(s2, REG_FTMP2);
896 M_FMUL(s1, REG_FTMP2);
897 M_FLTMOVE(REG_FTMP2, d);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
902 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
903 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
904 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
905 M_DBLMOVE(s2, REG_FTMP2);
906 M_DMUL(s1, REG_FTMP2);
907 M_DBLMOVE(REG_FTMP2, d);
908 emit_store_dst(jd, iptr, d);
911 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
912 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
913 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
914 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
915 M_FLTMOVE(s1, REG_FTMP1);
916 M_FDIV(s2, REG_FTMP1);
917 M_FLTMOVE(REG_FTMP1, d);
918 emit_store_dst(jd, iptr, d);
921 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
922 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
923 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
924 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
925 M_DBLMOVE(s1, REG_FTMP1);
926 M_DDIV(s2, REG_FTMP1);
927 M_DBLMOVE(REG_FTMP1, d);
928 emit_store_dst(jd, iptr, d);
931 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
932 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
933 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
934 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
935 M_FLTMOVE(s2, REG_FTMP2);
936 M_FADD(s1, REG_FTMP2);
937 M_FLTMOVE(REG_FTMP2, d);
938 emit_store_dst(jd, iptr, d);
941 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
942 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
943 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
944 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
945 M_DBLMOVE(s2, REG_FTMP2);
946 M_DADD(s1, REG_FTMP2);
947 M_DBLMOVE(REG_FTMP2, d);
948 emit_store_dst(jd, iptr, d);
951 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
952 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
953 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
954 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
955 M_FLTMOVE(s1, REG_FTMP1);
956 M_FSUB(s2, REG_FTMP1);
957 M_FLTMOVE(REG_FTMP1, d);
958 emit_store_dst(jd, iptr, d);
961 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
962 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
963 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
964 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
965 M_DBLMOVE(s1, REG_FTMP1);
966 M_DSUB(s2, REG_FTMP1);
967 M_DBLMOVE(REG_FTMP1, d);
968 emit_store_dst(jd, iptr, d);
971 case ICMD_F2D: /* ..., value ==> ..., (double) value */
972 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
973 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
975 emit_store_dst(jd, iptr, d);
978 case ICMD_D2F: /* ..., value ==> ..., (float) value */
979 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
980 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
982 emit_store_dst(jd, iptr, d);
985 case ICMD_FNEG: /* ..., value ==> ..., - value */
986 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
987 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
989 emit_store_dst(jd, iptr, d);
992 case ICMD_DNEG: /* ..., value ==> ..., - value */
993 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
994 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
996 emit_store_dst(jd, iptr, d);
1001 /* load/store/copy/move operations ************************************/
1003 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
1004 case ICMD_ALOAD: /* s1 = local variable */
1008 case ICMD_ISTORE: /* ..., value ==> ... */
1015 emit_copy(jd, iptr);
1020 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1021 emit_copy(jd, iptr);
1025 case ICMD_ACONST: /* ... ==> ..., constant */
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1028 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1029 constant_classref *cr = iptr->sx.val.c.ref;;
1030 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1033 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1035 emit_store_dst(jd, iptr, d);
1037 /* BRANCH *************************************************************/
1039 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1041 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1042 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1044 #ifdef ENABLE_VERIFIER
1045 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1046 unresolved_class *uc = iptr->sx.s23.s2.uc;
1048 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1050 #endif /* ENABLE_VERIFIER */
1051 M_JSR_PCREL(2); /* get current PC */
1054 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1059 case ICMD_GOTO: /* ... ==> ... */
1060 case ICMD_RET: /* ... ==> ... */
1062 emit_br(cd, iptr->dst.block);
1066 case ICMD_JSR: /* ... ==> ... */
1068 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1074 case ICMD_IFNULL: /* ..., value ==> ... */
1075 case ICMD_IFNONNULL:
1076 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1077 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1079 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1087 case ICMD_IFEQ: /* ..., value ==> ... */
1089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1090 assert (VAROP(iptr->s1)->type == TYPE_INT);
1091 M_ICMP_IMM(iptr->sx.val.i, s1);
1092 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1095 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1096 case ICMD_IF_ICMPNE:
1097 case ICMD_IF_ICMPLT:
1098 case ICMD_IF_ICMPGT:
1099 case ICMD_IF_ICMPLE:
1100 case ICMD_IF_ICMPGE:
1102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1103 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1105 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1108 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1109 case ICMD_IF_ACMPNE:
1111 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1112 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1114 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1118 /* MEMORY *************************************************************/
1119 case ICMD_GETSTATIC:
1120 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1121 uf = iptr->sx.s23.s3.uf;
1122 fieldtype = uf->fieldref->parseddesc.fd->type;
1123 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1125 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1127 fieldtype = fi->type;
1128 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1129 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
1132 disp = (ptrint) &(fi->value);
1134 M_AMOV_IMM(disp, REG_ATMP1);
1135 switch (fieldtype) {
1136 #if defined(ENABLE_SOFTFLOAT)
1140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1141 M_ILD(d, REG_ATMP1, 0);
1144 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1145 M_ALD(d, REG_ATMP1, 0);
1147 #if defined(ENABLE_SOFTFLOAT)
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1152 M_LLD(d, REG_ATMP1, 0);
1154 #if !defined(ENABLE_SOFTFLOAT)
1156 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1157 M_FLD(d, REG_ATMP1, 0);
1160 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1161 M_DLD(d, REG_ATMP1, 0);
1165 emit_store_dst(jd, iptr, d);
1168 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1170 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1171 uf = iptr->sx.s23.s3.uf;
1172 fieldtype = uf->fieldref->parseddesc.fd->type;
1174 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1176 fi = iptr->sx.s23.s3.fmiref->p.field;
1177 fieldtype = fi->type;
1178 disp = &(fi->value);
1180 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1181 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class, 0);
1184 M_AMOV_IMM(disp, REG_ATMP1);
1185 switch (fieldtype) {
1186 #if defined(ENABLE_SOFTFLOAT)
1190 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1191 M_IST(s1, REG_ATMP1, 0);
1193 #if defined(ENABLE_SOFTFLOAT)
1197 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1198 M_LST(s1, REG_ATMP1, 0);
1201 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1202 M_AST(s1, REG_ATMP1, 0);
1204 #if !defined(ENABLE_SOFTFLOAT)
1206 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1207 M_FST(s1, REG_ATMP1, 0);
1210 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1211 M_DST(s1, REG_ATMP1, 0);
1218 case ICMD_GETFIELD: /* ... ==> ..., value */
1220 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1222 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1223 uf = iptr->sx.s23.s3.uf;
1224 fieldtype = uf->fieldref->parseddesc.fd->type;
1227 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1230 fi = iptr->sx.s23.s3.fmiref->p.field;
1231 fieldtype = fi->type;
1235 /* implicit null-pointer check */
1236 switch (fieldtype) {
1237 #if defined(ENABLE_SOFTFLOAT)
1241 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1244 #if defined(ENABLE_SOFTFLOAT)
1248 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1252 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1255 #if !defined(ENABLE_SOFTFLOAT)
1257 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1261 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1266 emit_store_dst(jd, iptr, d);
1269 case ICMD_PUTFIELD: /* ..., value ==> ... */
1271 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1273 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1274 uf = iptr->sx.s23.s3.uf;
1275 fieldtype = uf->fieldref->parseddesc.fd->type;
1279 fi = iptr->sx.s23.s3.fmiref->p.field;
1280 fieldtype = fi->type;
1284 if (IS_INT_LNG_TYPE(fieldtype)) {
1285 if (IS_2_WORD_TYPE(fieldtype)) {
1286 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1288 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1291 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1295 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1297 /* implicit null-pointer check */
1298 switch (fieldtype) {
1299 #if defined(ENABLE_SOFTFLOAT)
1303 M_IST(s2, s1, disp);
1306 #if defined(ENABLE_SOFTFLOAT)
1310 M_LST(s2, s1, disp);
1313 M_AST(s2, s1, disp);
1315 #if !defined(ENABLE_SOFTFLOAT)
1317 M_FST(s2, s1, disp);
1320 M_DST(s2, s1, disp);
1326 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1328 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1329 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1330 /* implicit null-pointer check */
1331 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1332 emit_store_dst(jd, iptr, d);
1335 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1337 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1338 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1339 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1340 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1341 M_INTMOVE(s2, REG_ITMP2);
1342 M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1343 M_ADRMOVE(s1, REG_ATMP1);
1344 M_AADDINT(REG_ITMP2, REG_ATMP1);
1345 /* implicit null-pointer check */
1346 M_LBZX(REG_ATMP1, d);
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1353 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1354 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1355 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1356 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1357 M_INTMOVE(s2, REG_ITMP2);
1358 M_ISSL_IMM(1, REG_ITMP2);
1359 M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2);
1360 M_ADRMOVE(s1, REG_ATMP1);
1361 M_AADDINT(REG_ITMP2, REG_ATMP1);
1362 /* implicit null-pointer check */
1363 M_LHZX(REG_ATMP1, d);
1365 emit_store_dst(jd, iptr, d);
1368 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1370 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1371 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1373 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1374 M_INTMOVE(s2, REG_ITMP2);
1375 M_ISSL_IMM(1, REG_ITMP2);
1376 M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1377 M_ADRMOVE(s1, REG_ATMP1);
1378 M_AADDINT(REG_ITMP2, REG_ATMP1);
1380 /* implicit null-pointer check */
1381 M_LHZX(REG_ATMP1, d);
1383 emit_store_dst(jd, iptr, d);
1386 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1388 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1389 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1390 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1391 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1392 M_INTMOVE(s2, REG_ITMP2);
1393 M_ISSL_IMM(2, REG_ITMP2);
1394 M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1395 M_ADRMOVE(s1, REG_ATMP1);
1396 M_AADDINT(REG_ITMP2, REG_ATMP1);
1397 /* implicit null-pointer check */
1398 M_LWZX(REG_ATMP1, d);
1399 emit_store_dst(jd, iptr, d);
1402 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1403 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1404 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1405 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1406 /* implicit null-pointer check */
1407 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1408 M_INTMOVE(s2, REG_ITMP1);
1409 M_ISSL_IMM(3, REG_ITMP1);
1410 M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1);
1411 M_ADRMOVE(s1, REG_ATMP1);
1412 M_AADDINT(REG_ITMP1, REG_ATMP1);
1413 /* implicit null-pointer check */
1414 M_LLD(d, REG_ATMP1, 0);
1415 emit_store_dst(jd, iptr, d);
1418 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1419 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1420 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1421 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1422 M_INTMOVE(s2, REG_ITMP2);
1423 M_ISSL_IMM(2, REG_ITMP2);
1424 M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2);
1425 M_ADRMOVE(s1, REG_ATMP1);
1426 M_AADDINT(REG_ITMP2, REG_ATMP1);
1427 /* implicit null-pointer check */
1428 #if !defined(ENABLE_SOFTFLOAT)
1429 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1430 M_FLD(d, REG_ATMP1, 0);
1432 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1433 M_LWZX(REG_ATMP1, d);
1435 emit_store_dst(jd, iptr, d);
1438 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1439 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1440 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1441 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1442 M_INTMOVE(s2, REG_ITMP2);
1443 M_ISSL_IMM(3, REG_ITMP2);
1444 M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2);
1445 M_ADRMOVE(s1, REG_ATMP1);
1446 M_AADDINT(REG_ITMP2, REG_ATMP1);
1447 /* implicit null-pointer check */
1448 #if !defined(ENABLE_SOFTFLOAT)
1449 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1450 M_DLD(d, REG_ATMP1, 0);
1452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1453 M_LLD(d, REG_ATMP1, 0);
1455 emit_store_dst(jd, iptr, d);
1458 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1459 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1460 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1461 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1462 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1463 M_INTMOVE(s2, REG_ITMP2);
1464 M_ISSL_IMM(2, REG_ITMP2);
1465 M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP2);
1466 M_ADRMOVE(s1, REG_ATMP1);
1467 M_AADDINT(REG_ITMP2, REG_ATMP1);
1469 /* implicit null-pointer check */
1470 M_LAX(REG_ATMP1, d);
1471 emit_store_dst(jd, iptr, d);
1475 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1476 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1478 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1479 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1480 M_INTMOVE(s2, REG_ITMP2);
1481 M_IADD_IMM(OFFSET(java_bytearray, data[0]), REG_ITMP2);
1482 M_ADRMOVE(s1, REG_ATMP1);
1483 M_AADDINT(REG_ITMP2, REG_ATMP1);
1484 /* implicit null-pointer check */
1485 M_STBX(REG_ATMP1, s3);
1488 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1490 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1491 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1492 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1493 M_INTMOVE(s2, REG_ITMP2);
1494 M_ISSL_IMM(1, REG_ITMP2);
1495 M_IADD_IMM(OFFSET(java_chararray, data[0]), REG_ITMP2);
1496 M_ADRMOVE(s1, REG_ATMP1);
1497 M_AADDINT(REG_ITMP2, REG_ATMP1);
1498 /* implicit null-pointer check */
1499 M_STHX(REG_ATMP1, s3);
1502 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1504 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1505 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1506 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1507 M_INTMOVE(s2, REG_ITMP2);
1508 M_ISSL_IMM(1, REG_ITMP2);
1509 M_IADD_IMM(OFFSET(java_shortarray, data[0]), REG_ITMP2);
1510 M_ADRMOVE(s1, REG_ATMP1);
1511 M_AADDINT(REG_ITMP2, REG_ATMP1);
1512 /* implicit null-pointer check */
1513 M_STHX(REG_ATMP1, s3);
1516 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1520 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1521 M_INTMOVE(s2, REG_ITMP2);
1522 M_ISSL_IMM(2, REG_ITMP2);
1523 M_IADD_IMM(OFFSET(java_intarray, data[0]), REG_ITMP2);
1524 M_ADRMOVE(s1, REG_ATMP1);
1525 M_AADDINT(REG_ITMP2, REG_ATMP1);
1526 /* implicit null-pointer check */
1527 M_STWX(REG_ATMP1, s3);
1530 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1531 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1533 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1535 M_INTMOVE(s2, REG_ITMP1);
1536 M_ISSL_IMM(3, REG_ITMP1);
1537 M_IADD_IMM(OFFSET(java_longarray, data[0]), REG_ITMP1);
1538 M_ADRMOVE(s1, REG_ATMP1);
1539 M_AADDINT(REG_ITMP1, REG_ATMP1);
1540 /* implicit null-pointer check */
1541 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1542 M_LST(s3, REG_ATMP1, 0);
1545 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1547 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1548 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1549 M_INTMOVE(s2, REG_ITMP2);
1550 M_ISSL_IMM(2, REG_ITMP2);
1551 M_IADD_IMM(OFFSET(java_floatarray, data[0]), REG_ITMP2);
1552 M_ADRMOVE(s1, REG_ATMP1);
1553 M_AADDINT(REG_ITMP2, REG_ATMP1);
1554 /* implicit null-pointer check */
1555 #if !defined(ENABLE_SOFTFLOAT)
1556 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1557 M_FST(s3, REG_ATMP1, 0);
1559 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1560 M_STWX(REG_ATMP1, s3);
1564 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1566 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1567 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1568 M_INTMOVE(s2, REG_ITMP2);
1569 M_ISSL_IMM(3, REG_ITMP2);
1570 M_IADD_IMM(OFFSET(java_doublearray, data[0]), REG_ITMP2);
1571 M_ADRMOVE(s1, REG_ATMP1);
1572 M_AADDINT(REG_ITMP2, REG_ATMP1);
1573 /* implicit null-pointer check */
1574 #if !defined(ENABLE_SOFTFLOAT)
1575 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1576 M_DST(s3, REG_ATMP1, 0);
1578 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1579 /* implicit null-pointer check */
1580 M_LST(s3, REG_ATMP1, 0);
1584 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1586 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1587 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1588 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1589 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1591 /* XXX what if array is NULL */
1592 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1594 M_AST(s1, REG_SP, 0*4);
1595 M_AST(s3, REG_SP, 1*4);
1596 M_JSR_IMM(BUILTIN_canstore);
1597 emit_exception_check(cd, iptr);
1599 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1600 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1601 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1602 M_INTMOVE(s2, REG_ITMP1);
1603 M_ISSL_IMM(2, REG_ITMP1);
1604 M_IADD_IMM(OFFSET(java_objectarray, data[0]), REG_ITMP1);
1605 M_ADRMOVE(s1, REG_ATMP1);
1606 M_AADDINT(REG_ITMP1, REG_ATMP1);
1607 /* implicit null-pointer check */
1608 M_STAX(REG_ATMP1, s3);
1613 /* METHOD INVOCATION *********************************************************/
1614 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1615 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1617 bte = iptr->sx.s23.s3.bte;
1621 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1622 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1623 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1624 case ICMD_INVOKEINTERFACE:
1625 REPLACEMENT_POINT_INVOKE(cd, iptr);
1627 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1629 um = iptr->sx.s23.s3.um;
1630 md = um->methodref->parseddesc.md;
1633 lm = iptr->sx.s23.s3.fmiref->p.method;
1635 md = lm->parseddesc;
1638 s3 = md->paramcount;
1640 MCODECHECK((s3 << 1) + 64);
1642 /* copy arguments to stack */
1643 for (s3 = s3 - 1; s3 >= 0; s3--) {
1644 var = VAR(iptr->sx.s23.s2.args[s3]);
1645 /* already preallocated */
1646 if (var->flags & PREALLOC) continue;
1648 if (!md->params[s3].inmemory) assert(0);
1650 switch (var->type) {
1651 #if defined(ENABLE_SOFTFLOAT)
1655 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1656 M_LST(d, REG_SP, md->params[s3].regoff);
1658 #if defined(ENABLE_SOFTFLOAT)
1662 d = emit_load(jd, iptr, var, REG_ITMP1);
1663 M_IST(d, REG_SP, md->params[s3].regoff);
1666 d = emit_load(jd, iptr, var, REG_ATMP1);
1667 M_AST(d, REG_SP, md->params[s3].regoff);
1669 #if !defined(ENABLE_SOFTFLOAT)
1671 d = emit_load(jd, iptr, var, REG_FTMP1);
1672 M_FST(d, REG_SP, md->params[s3].regoff);
1675 d = emit_load(jd, iptr, var, REG_FTMP1);
1676 M_DST(d, REG_SP, md->params[s3].regoff);
1684 /* arguments in place now */
1687 disp = (ptrint) bte->fp;
1688 d = md->returntype.type;
1691 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1692 emit_exception_check(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 codegen_addpatchref(cd, 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 codegen_addpatchref(cd, 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_objectheader, vftbl));
1727 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1728 /* generate the actual call */
1731 case ICMD_INVOKEINTERFACE:
1733 codegen_addpatchref(cd, 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_objectheader, 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 codegen_addpatchref(cd, 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 && (m->flags & ACC_SYNCHRONIZED)) {
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 (!jd->isleafmethod) {
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 codegen_addpatchref(cd, 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 codegen_addpatchref(cd, 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_objectheader, 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 codegen_addpatchref(cd, 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_objectheader, 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 codegen_addpatchref(cd, 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 codegen_addpatchref(cd, 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_objectheader, 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 codegen_addpatchref(cd, 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_objectheader, 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 codegen_addpatchref(cd, 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 codegen_addpatchref(cd, 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 dseg_createlinenumbertable(cd);
2373 /* generate stubs */
2374 emit_patcher_stubs(jd);
2375 REPLACEMENT_EMIT_STUBS(jd);
2381 /* codegen_emit_stub_compiler **************************************************
2383 Emits a stub routine which calls the compiler.
2385 *******************************************************************************/
2387 void codegen_emit_stub_compiler(jitdata *jd)
2392 /* get required compiler data */
2397 /* code for the stub */
2399 M_AMOV_IMM(m, REG_ATMP1);
2400 M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2404 /* codegen_emit_stub_builtin ***************************************************
2406 Creates a stub routine which calls a builtin function.
2408 *******************************************************************************/
2410 void codegen_emit_stub_builtin(jitdata *jd, builtintable_entry *bte)
2419 /* get required compiler data */
2423 /* set some variables */
2426 /* calculate stack frame size */
2427 cd->stackframesize =
2428 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2429 4; /* 4 arguments or return value */
2431 /* create method header */
2432 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2433 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
2434 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2435 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2436 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2437 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2438 (void) dseg_addlinenumbertablesize(cd);
2439 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2441 /* generate stub code */
2442 M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2444 #if defined(ENABLE_GC_CACAO)
2445 /* Save callee saved integer registers in stackframeinfo (GC may
2446 need to recover them during a collection). */
2448 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
2449 OFFSET(stackframeinfo, adrregs);
2451 for (i = 0; i < ADR_SAV_CNT; i++)
2452 M_AST(abi_registers_address_saved[i], REG_SP, disp + i * 4);
2455 /* create dynamic stack info */
2457 M_AMOV(REG_SP, REG_ATMP1);
2458 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2459 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* datasp */
2461 M_AMOV_IMM(0, REG_ATMP1); /* we need pv patched in */
2462 dseg_adddata(cd); /* this does the trick */
2463 M_AST(REG_ATMP1, REG_SP, 1 * 4); /* pv */
2465 M_AMOV(REG_SP, REG_ATMP1);
2466 M_AADD_IMM(cd->stackframesize * 4 + SIZEOF_VOID_P, REG_ATMP1);
2467 M_AST(REG_ATMP1, REG_SP, 2 * 4); /* sp */
2469 M_ALD(REG_ATMP3, REG_SP, cd->stackframesize * 4);
2470 M_AST(REG_ATMP3, REG_SP, 3 * 4); /* ra */
2472 M_JSR_IMM(codegen_stub_builtin_enter);
2474 /* builtins are allowed to have 4 arguments max */
2476 assert(md->paramcount <= 4);
2478 /* copy arguments into new stackframe */
2480 for (i = 0; i < md->paramcount; i++) {
2481 if (!md->params[i].inmemory) {
2482 log_text("No integer argument registers available!");
2485 } else { /* float/double in memory can be copied like int/longs */
2486 s1 = (md->params[i].regoff + cd->stackframesize + 1) * 4;
2487 s2 = md->params[i].regoff * 4;
2489 M_ILD(REG_ITMP1, REG_SP, s1);
2490 M_IST(REG_ITMP1, REG_SP, s2);
2491 if (IS_2_WORD_TYPE(md->paramtypes[i].type)) {
2492 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2493 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2499 /* call the builtin function */
2501 M_AMOV_IMM(bte->fp, REG_ATMP3);
2504 /* save return value */
2505 switch (md->returntype.type) {
2506 case TYPE_VOID: break;
2508 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2511 M_IST(REG_D1, REG_SP, 2 * 4);
2517 M_IST(REG_D0, REG_SP, 1 * 4);
2523 /* remove native stackframe info */
2525 M_AMOV(REG_SP, REG_ATMP1);
2526 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2527 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2529 M_JSR_IMM(codegen_stub_builtin_exit);
2531 /* restore return value */
2532 switch (md->returntype.type) {
2533 case TYPE_VOID: break;
2537 M_ILD(REG_D1, REG_SP, 2 * 4);
2543 M_ILD(REG_D0, REG_SP, 1 * 4);
2549 #if defined(ENABLE_GC_CACAO)
2550 /* Restore callee saved integer registers from stackframeinfo (GC
2551 might have modified them during a collection). */
2553 disp = cd->stackframesize * 4 - sizeof(stackframeinfo) +
2554 OFFSET(stackframeinfo, adrregs);
2556 for (i = 0; i < ADR_SAV_CNT; i++)
2557 M_ALD(abi_registers_address_saved[i], REG_SP, disp + i * 4);
2560 /* remove stackframe */
2561 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2568 /* codegen_emit_stub_native ****************************************************
2570 Emits a stub routine which calls a native method.
2572 *******************************************************************************/
2574 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2581 s4 nativeparams, i, j, t, s1, s2;
2583 /* get required compiler data */
2591 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2593 /* calc stackframe size */
2594 cd->stackframesize = sizeof(stackframeinfo) / SIZEOF_VOID_P +
2595 sizeof(localref_table) / SIZEOF_VOID_P +
2597 1 + /* functionptr */
2598 4; /* args for codegen_start_native_call */
2600 /* create method header */
2601 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2602 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
2603 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2604 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2605 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2606 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2607 (void) dseg_addlinenumbertablesize(cd);
2608 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2610 /* print call trace */
2611 #if !defined(NDEBUG)
2612 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2613 emit_verbosecall_enter(jd);
2618 M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2620 /* get function address (this must happen before the stackframeinfo) */
2621 #if !defined(WITH_STATIC_CLASSPATH)
2623 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2626 M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2628 M_AST(REG_ATMP2, REG_SP, 4 * 4);
2630 /* put arguments for codegen_start_native_call onto stack */
2631 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2633 M_AMOV(REG_SP, REG_ATMP1);
2634 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2636 M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
2637 M_AST(REG_ATMP3, REG_SP, 3 * 4); /* ra */
2639 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* datasp */
2641 M_AADD_IMM(1 * 4 , REG_ATMP1);
2642 M_AST(REG_ATMP1, REG_SP, 2 * 4); /* sp */
2644 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2645 dseg_adddata(cd); /* this patches it */
2647 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2649 M_JSR_IMM(codegen_start_native_call);
2651 /* load function pointer */
2652 M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2654 /* copy arguments into stackframe */
2655 for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j) {
2656 t = md->paramtypes[i].type;
2657 /* all arguments via stack */
2658 assert(md->params[i].inmemory);
2660 s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2661 s2 = nmd->params[j].regoff;
2663 /* simply copy argument stack */
2664 M_ILD(REG_ITMP1, REG_SP, s1);
2665 M_IST(REG_ITMP1, REG_SP, s2);
2666 if (IS_2_WORD_TYPE(t)) {
2667 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2668 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2672 /* for static function class as second arg */
2673 if (m->flags & ACC_STATIC) {
2674 M_AMOV_IMM(m->class, REG_ATMP1);
2675 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2677 /* env ist first argument */
2678 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2679 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2681 /* call the native function */
2684 /* save return value */
2685 switch (md->returntype.type) {
2686 case TYPE_VOID: break;
2688 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2691 M_IST(REG_D1, REG_SP, 2 * 4);
2697 M_IST(REG_D0, REG_SP, 1 * 4);
2703 /* print call trace */
2704 #if ! defined(NDEBUG)
2705 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2706 emit_verbosecall_exit(jd);
2709 /* remove native stackframe info */
2710 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2712 M_AMOV(REG_SP, REG_ATMP3);
2713 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2714 M_AST(REG_ATMP3, REG_SP, 0 * 4); /* datasp */
2715 M_JSR_IMM(codegen_finish_native_call);
2717 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2718 /* restore return value */
2719 switch (md->returntype.type) {
2720 case TYPE_VOID: break;
2724 M_ILD(REG_D1, REG_SP, 2 * 4);
2729 M_ILD(REG_D0, REG_SP, 1 * 4);
2734 #if !defined(ENABLE_SOFTFLOAT)
2735 /* additionally load values into floating points registers
2736 * as cacao jit code expects them there */
2737 switch (md->returntype.type) {
2739 M_FLD(REG_D0, REG_SP, 1 * 4);
2742 M_DLD(REG_D0, REG_SP, 1 * 4);
2746 /* restore saved registers */
2748 M_AADD_IMM(cd->stackframesize*4, REG_SP);
2749 /* check for exception */
2754 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2756 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2757 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2758 M_JMP_IMM(asm_handle_nat_exception);
2760 /* should never be reached from within jit code*/
2763 /* generate patcher stub call code */
2764 emit_patcher_stubs(jd);
2769 * These are local overrides for various environment variables in Emacs.
2770 * Please do not remove this and leave it at the end of the file, where
2771 * Emacs will automagically detect them.
2772 * ---------------------------------------------------------------------
2775 * indent-tabs-mode: t
2779 * vim:noexpandtab:sw=4:ts=4: