1 /* src/vm/jit/m68k/codegen.c - machine code generator for m68k
3 Copyright (C) 1996-2005, 2006, 2007, 2008, 2009
4 CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
6 This file is part of CACAO.
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2, or (at
11 your option) any later version.
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
34 #include "vm/jit/m68k/codegen.h"
35 #include "vm/jit/m68k/emit.h"
37 #include "mm/memory.hpp"
39 #include "native/localref.hpp"
40 #include "native/native.hpp"
42 #include "threads/lock.hpp"
44 #include "vm/jit/builtin.hpp"
45 #include "vm/exceptions.hpp"
46 #include "vm/global.h"
47 #include "vm/loader.hpp"
48 #include "vm/options.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.hpp"
54 #include "vm/jit/patcher-common.hpp"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/linenumbertable.hpp"
57 #include "vm/jit/emit-common.hpp"
58 #include "vm/jit/jit.hpp"
59 #include "vm/jit/abi.h"
60 #include "vm/jit/parse.hpp"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/stacktrace.hpp"
63 #include "vm/jit/trap.hpp"
67 * Generates machine code for the method prolog.
69 void codegen_emit_prolog(jitdata* jd)
78 // Get required compiler data.
79 methodinfo* m = jd->m;
80 codeinfo* code = jd->code;
81 codegendata* cd = jd->cd;
82 registerdata* rd = jd->rd;
85 // XXX Fix the below stuff, cd->stackframesize is a slot counter
86 // and not a byte counter!!!
89 /* create stack frame */
90 M_AADD_IMM(-(cd->stackframesize), REG_SP);
92 /* save used callee saved registers */
93 p = cd->stackframesize;
94 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
95 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
97 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
98 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
100 #if !defined(ENABLE_SOFTFLOAT)
101 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
102 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
105 assert(FLT_SAV_CNT == 0);
106 assert(rd->savfltreguse == 0);
108 /* take arguments out of stack frame */
110 for (p = 0, l = 0; p < md->paramcount; p++) {
111 t = md->paramtypes[p].type;
112 varindex = jd->local_map[l * 5 + t];
115 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
118 if (varindex == UNUSED)
123 s1 = md->params[p].regoff;
124 assert(md->params[p].inmemory); /* all args are on stack */
127 #if defined(ENABLE_SOFTFLOAT)
133 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
134 if (IS_2_WORD_TYPE(t)) {
135 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
137 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
139 } else { /* stack arg -> spilled */
140 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
141 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
142 if (IS_2_WORD_TYPE(t)) {
143 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
144 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
148 #if !defined(ENABLE_SOFTFLOAT)
151 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
152 if (IS_2_WORD_TYPE(t)) {
153 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
155 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
157 } else { /* stack-arg -> spilled */
158 if (IS_2_WORD_TYPE(t)) {
159 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
160 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
162 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
163 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
167 #endif /* SOFTFLOAT */
169 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
170 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
171 } else { /* stack-arg -> spilled */
172 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
173 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
178 } /* end for argument out of stack*/
183 * Generates machine code for the method epilog.
185 void codegen_emit_epilog(jitdata* jd)
190 // Get required compiler data.
191 codeinfo* code = jd->code;
192 codegendata* cd = jd->cd;
193 registerdata* rd = jd->rd;
195 p = cd->stackframesize;
197 /* restore return address */
200 if (!code_is_leafmethod(code)) {
201 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
202 may have a displacement overflow. */
204 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
209 /* restore saved registers */
211 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
212 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
214 for (i = ADR_SAV_CNT - 1; i >= rd->savadrreguse; --i) {
215 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
217 #if !defined(ENABLE_SOFTFLOAT)
218 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
219 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
223 /* deallocate stack */
224 M_AADD_IMM(cd->stackframesize, REG_SP);
230 * Generates machine code for one ICMD.
232 void codegen_emit_instruction(jitdata* jd, instruction* iptr)
235 builtintable_entry* bte;
236 methodinfo* lm; // Local methodinfo for ICMD_INVOKE*.
237 unresolved_method* um;
239 unresolved_field* uf;
241 int32_t s1, s2, s3, d;
244 // Get required compiler data.
245 codeinfo* code = jd->code;
246 codegendata* cd = jd->cd;
250 /* CONST **************************************************************/
252 case ICMD_FCONST: /* ... ==> ..., constant */
254 #if defined(ENABLE_SOFTFLOAT)
255 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
256 M_IMOV_IMM(iptr->sx.val.i, d);
257 emit_store_dst(jd, iptr, d);
259 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
260 FCONST(iptr->sx.val.i, d);
261 emit_store_dst(jd, iptr, d);
265 case ICMD_DCONST: /* ... ==> ..., constant */
267 #if defined(ENABLE_SOFTFLOAT)
268 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
269 LCONST(iptr->sx.val.l, d);
270 emit_store_dst(jd, iptr, d);
272 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
273 disp = dseg_add_double(cd, iptr->sx.val.d);
274 M_AMOV_IMM(0, REG_ATMP1);
276 M_DLD(d, REG_ATMP1, disp);
277 emit_store_dst(jd, iptr, d);
282 /* some long operations *********************************************/
283 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
284 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
285 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
286 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
287 M_INTMOVE(s2, REG_ITMP1);
288 M_IADD(s1, REG_ITMP1); /* low word */
289 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
290 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
291 M_INTMOVE(s2, REG_ITMP2);
292 M_IADDX(s1, REG_ITMP2); /* high word */
293 emit_store_dst(jd, iptr, d);
296 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
297 /* sx.val.l = constant */
298 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
299 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
302 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
304 s3 = iptr->sx.val.l & 0xffffffff;
305 M_INTMOVE(s1, REG_ITMP1);
306 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
308 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
309 M_LNGMOVE(REG_ITMP12_PACKED, d);
310 emit_store_dst(jd, iptr, d);
313 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
314 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
315 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
317 M_INTMOVE(s1, REG_ITMP1);
318 M_ISUB(s2, REG_ITMP1); /* low word */
319 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
320 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
321 M_INTMOVE(s1, REG_ITMP2);
322 M_ISUBX(s2, REG_ITMP2); /* high word */
323 emit_store_dst(jd, iptr, d);
326 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
327 /* sx.val.l = constant */
328 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
329 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
330 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
332 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
334 s3 = (-iptr->sx.val.l) & 0xffffffff;
335 M_INTMOVE(s1, REG_ITMP1);
336 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
338 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
339 M_LNGMOVE(REG_ITMP12_PACKED, d);
340 emit_store_dst(jd, iptr, d);
343 case ICMD_LNEG: /* ..., value ==> ..., - value */
344 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
345 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
346 M_LNGMOVE(s1, REG_ITMP12_PACKED);
347 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
348 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
349 M_LNGMOVE(REG_ITMP12_PACKED, d);
350 emit_store_dst(jd, iptr, d);
353 /* integer operations ************************************************/
354 case ICMD_INEG: /* ..., value ==> ..., - value */
356 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
357 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
358 M_INTMOVE(s1, REG_ITMP1);
360 M_INTMOVE(REG_ITMP1, d);
361 emit_store_dst(jd, iptr, d);
364 case ICMD_I2L: /* ..., value ==> ..., value */
366 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
368 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
370 M_ISET(GET_HIGH_REG(d));
372 M_ICLR(GET_HIGH_REG(d));
374 emit_store_dst(jd, iptr, d);
377 case ICMD_L2I: /* ..., value ==> ..., value */
379 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
380 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
382 emit_store_dst(jd, iptr, d);
384 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
389 emit_store_dst(jd, iptr, d);
392 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
397 emit_store_dst(jd, iptr, d);
400 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
403 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
405 emit_store_dst(jd, iptr, d);
410 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
412 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
413 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
414 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
415 M_INTMOVE(s2, REG_ITMP2);
416 M_IADD(s1, REG_ITMP2);
417 M_INTMOVE(REG_ITMP2, d);
418 emit_store_dst(jd, iptr, d);
421 /* s1.localindex = variable, sx.val.i = constant*/
426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
427 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
428 M_INTMOVE(s1, REG_ITMP1);
429 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
430 M_INTMOVE(REG_ITMP1, d);
431 emit_store_dst(jd, iptr, d);
434 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
437 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
438 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
439 M_INTMOVE(s1, REG_ITMP1);
440 M_ISUB(s2, REG_ITMP1);
441 M_INTMOVE(REG_ITMP1, d);
442 emit_store_dst(jd, iptr, d);
445 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
446 /* sx.val.i = constant */
448 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
449 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
450 M_INTMOVE(s1, REG_ITMP1);
451 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
452 M_INTMOVE(REG_ITMP1, d);
453 emit_store_dst(jd, iptr, d);
456 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
457 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
458 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
459 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
460 emit_arithmetic_check(cd, iptr, s2);
461 M_INTMOVE(s1, REG_ITMP1);
462 M_IDIV(s2, REG_ITMP1);
463 M_INTMOVE(REG_ITMP1, d);
464 emit_store_dst(jd, iptr, d);
467 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
468 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
469 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
470 M_INTMOVE(s1, REG_ITMP1);
474 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
476 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
477 M_ISSR(REG_ITMP2, REG_ITMP1);
478 M_INTMOVE(REG_ITMP1, d);
479 emit_store_dst(jd, iptr, d);
482 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
484 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
486 emit_arithmetic_check(cd, iptr, s2);
488 M_ICMP_IMM(0x80000000, s1);
493 M_TPFL; /* hides the next instruction */
494 M_IREM(s2, s1, REG_ITMP3);
496 M_INTMOVE(REG_ITMP3, d);
498 emit_store_dst(jd, iptr, d);
501 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
502 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
503 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
505 M_IMOV(s1, REG_ITMP1);
509 M_IAND_IMM(iptr->sx.val.i, d);
511 M_BGE(2 + 2 + 6 + 2);
512 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
514 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
517 emit_store_dst(jd, iptr, d);
521 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
522 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
524 bte = iptr->sx.s23.s3.bte;
527 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
528 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
529 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
530 /* XXX could be optimized */
531 emit_arithmetic_check(cd, iptr, REG_ITMP3);
533 M_LST(s2, REG_SP, 2 * 4);
534 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
535 M_LST(s1, REG_SP, 0 * 4);
539 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
540 M_LNGMOVE(REG_RESULT_PACKED, d);
541 emit_store_dst(jd, iptr, d);
544 case ICMD_IMUL: /* ..., 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_IMUL(s1, REG_ITMP2);
551 M_INTMOVE(REG_ITMP2, d);
552 emit_store_dst(jd, iptr, d);
555 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
556 /* sx.val.i = constant */
557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
558 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
559 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
560 M_IMUL(s1, REG_ITMP2);
561 M_INTMOVE(REG_ITMP2, d);
562 emit_store_dst(jd, iptr, d);
565 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
569 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
570 M_INTMOVE(s1, REG_ITMP1);
571 M_INTMOVE(s2, REG_ITMP2);
572 M_IAND_IMM(0x1f, REG_ITMP2);
573 M_ISSL(REG_ITMP2, REG_ITMP1);
574 M_INTMOVE(REG_ITMP1, d);
575 emit_store_dst(jd, iptr, d);
578 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
579 /* sx.val.i = constant */
581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
583 if (iptr->sx.val.i & 0x1f) {
584 M_INTMOVE(s1, REG_ITMP1)
585 if ((iptr->sx.val.i & 0x1f) <= 7) {
586 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
588 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
589 M_ISSL(REG_ITMP2, REG_ITMP1);
591 M_INTMOVE(REG_ITMP1, d);
595 emit_store_dst(jd, iptr, d);
598 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
603 M_INTMOVE(s1, REG_ITMP1);
604 M_INTMOVE(s2, REG_ITMP2);
605 M_IAND_IMM(0x1f, REG_ITMP2);
606 M_ISSR(REG_ITMP2, REG_ITMP1);
607 M_INTMOVE(REG_ITMP1, d);
608 emit_store_dst(jd, iptr, d);
611 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
612 /* sx.val.i = constant */
614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
616 if (iptr->sx.val.i & 0x1f) {
617 M_INTMOVE(s1, REG_ITMP1)
618 if ((iptr->sx.val.i & 0x1f) <= 7) {
619 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
621 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
622 M_ISSR(REG_ITMP2, REG_ITMP1);
624 M_INTMOVE(REG_ITMP1, d);
628 emit_store_dst(jd, iptr, d);
631 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
633 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
634 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
636 M_INTMOVE(s1, REG_ITMP1);
637 M_INTMOVE(s2, REG_ITMP2);
638 M_IAND_IMM(0x1f, REG_ITMP2);
639 M_IUSR(REG_ITMP2, REG_ITMP1);
640 M_INTMOVE(REG_ITMP1, d);
641 emit_store_dst(jd, iptr, d);
644 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
645 /* sx.val.i = constant */
646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
648 if (iptr->sx.val.i & 0x1f) {
649 M_INTMOVE(s1, REG_ITMP1)
650 if ((iptr->sx.val.i & 0x1f) <= 7) {
651 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
653 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
654 M_IUSR(REG_ITMP2, REG_ITMP1);
656 M_INTMOVE(REG_ITMP1, d);
660 emit_store_dst(jd, iptr, d);
663 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
668 M_INTMOVE(s2, REG_ITMP2);
669 M_IAND(s1, REG_ITMP2);
670 M_INTMOVE(REG_ITMP2, d);
671 emit_store_dst(jd, iptr, d);
674 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
675 /* sx.val.i = constant */
677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
679 M_INTMOVE(s1, REG_ITMP1);
680 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
681 M_INTMOVE(REG_ITMP1, d);
682 emit_store_dst(jd, iptr, d);
685 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
689 M_INTMOVE(s2, REG_ITMP2);
690 M_IOR(s1, REG_ITMP2);
691 M_INTMOVE(REG_ITMP2, d);
692 emit_store_dst(jd, iptr, d);
695 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
696 /* sx.val.i = constant */
697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
699 M_INTMOVE(s1, REG_ITMP1);
700 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
701 M_INTMOVE(REG_ITMP1, d);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
707 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
708 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
709 M_INTMOVE(s2, REG_ITMP2);
710 M_IXOR(s1, REG_ITMP2);
711 M_INTMOVE(REG_ITMP2, d);
712 emit_store_dst(jd, iptr, d);
715 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
716 /* sx.val.i = constant */
717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
718 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
719 M_INTMOVE(s1, REG_ITMP1);
720 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
721 M_INTMOVE(REG_ITMP1, d);
722 emit_store_dst(jd, iptr, d);
725 /* floating point operations ******************************************/
726 #if !defined(ENABLE_SOFTFLOAT)
727 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
729 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
730 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
734 M_BFUN(14); /* result is -1, branch to end */
735 M_BFLT(10); /* result is -1, branch to end */
737 M_BFEQ(4) /* result is 0, branch to end */
739 emit_store_dst(jd, iptr, d);
742 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
744 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
745 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
749 M_BFUN(16); /* result is +1, branch to end */
750 M_BFGT(14); /* result is +1, branch to end */
752 M_BFEQ(8) /* result is 0, branch to end */
754 emit_store_dst(jd, iptr, d);
757 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
758 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
759 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
760 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
761 emit_fmove(cd, s2, REG_FTMP2);
762 M_FMUL(s1, REG_FTMP2);
763 emit_fmove(cd, REG_FTMP2, d);
764 emit_store_dst(jd, iptr, d);
767 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
768 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
769 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
770 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
771 emit_dmove(cd, s2, REG_FTMP2);
772 M_DMUL(s1, REG_FTMP2);
773 emit_dmove(cd, REG_FTMP2, d);
774 emit_store_dst(jd, iptr, d);
777 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
778 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
779 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
780 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
781 emit_fmove(cd, s1, REG_FTMP1);
782 M_FDIV(s2, REG_FTMP1);
783 emit_fmove(cd, REG_FTMP1, d);
784 emit_store_dst(jd, iptr, d);
787 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
788 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
789 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
790 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
791 emit_dmove(cd, s1, REG_FTMP1);
792 M_DDIV(s2, REG_FTMP1);
793 emit_dmove(cd, REG_FTMP1, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
798 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
799 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
800 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
801 emit_fmove(cd, s2, REG_FTMP2);
802 M_FADD(s1, REG_FTMP2);
803 emit_fmove(cd, REG_FTMP2, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
808 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
809 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
810 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
811 emit_dmove(cd, s2, REG_FTMP2);
812 M_DADD(s1, REG_FTMP2);
813 emit_dmove(cd, REG_FTMP2, d);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
818 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
819 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
820 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
821 emit_fmove(cd, s1, REG_FTMP1);
822 M_FSUB(s2, REG_FTMP1);
823 emit_fmove(cd, REG_FTMP1, d);
824 emit_store_dst(jd, iptr, d);
827 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
828 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
829 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
830 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
831 emit_dmove(cd, s1, REG_FTMP1);
832 M_DSUB(s2, REG_FTMP1);
833 emit_dmove(cd, REG_FTMP1, d);
834 emit_store_dst(jd, iptr, d);
837 case ICMD_F2D: /* ..., value ==> ..., (double) value */
838 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
839 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
841 emit_store_dst(jd, iptr, d);
844 case ICMD_D2F: /* ..., value ==> ..., (float) value */
845 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
846 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
848 emit_store_dst(jd, iptr, d);
851 case ICMD_FNEG: /* ..., value ==> ..., - value */
852 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
853 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
855 emit_store_dst(jd, iptr, d);
858 case ICMD_DNEG: /* ..., value ==> ..., - value */
859 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
860 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
862 emit_store_dst(jd, iptr, d);
868 case ICMD_ACONST: /* ... ==> ..., constant */
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
871 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
872 constant_classref *cr = iptr->sx.val.c.ref;;
873 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, cr, 0);
876 M_AMOV_IMM(iptr->sx.val.anyptr, d);
878 emit_store_dst(jd, iptr, d);
880 /* BRANCH *************************************************************/
882 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
884 M_JSR_PCREL(2); /* get current PC */
887 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
891 /* MEMORY *************************************************************/
893 case ICMD_GETSTATIC: /* ... ==> ..., value */
895 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
896 uf = iptr->sx.s23.s3.uf;
897 fieldtype = uf->fieldref->parseddesc.fd->type;
900 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
903 fi = iptr->sx.s23.s3.fmiref->p.field;
904 fieldtype = fi->type;
905 disp = (intptr_t) fi->value;
907 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
908 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
913 M_AMOV_IMM(disp, REG_ATMP1);
915 #if defined(ENABLE_SOFTFLOAT)
919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
920 M_ILD(d, REG_ATMP1, 0);
923 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
924 M_ALD(d, REG_ATMP1, 0);
926 #if defined(ENABLE_SOFTFLOAT)
930 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
931 M_LLD(d, REG_ATMP1, 0);
933 #if !defined(ENABLE_SOFTFLOAT)
935 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
936 M_FLD(d, REG_ATMP1, 0);
939 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
940 M_DLD(d, REG_ATMP1, 0);
944 emit_store_dst(jd, iptr, d);
947 case ICMD_PUTSTATIC: /* ..., value ==> ... */
949 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
950 uf = iptr->sx.s23.s3.uf;
951 fieldtype = uf->fieldref->parseddesc.fd->type;
954 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, 0);
957 fi = iptr->sx.s23.s3.fmiref->p.field;
958 fieldtype = fi->type;
959 disp = (intptr_t) fi->value;
961 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz))
962 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz,
966 M_AMOV_IMM(disp, REG_ATMP1);
968 #if defined(ENABLE_SOFTFLOAT)
972 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
973 M_IST(s1, REG_ATMP1, 0);
975 #if defined(ENABLE_SOFTFLOAT)
979 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
980 M_LST(s1, REG_ATMP1, 0);
983 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
984 M_AST(s1, REG_ATMP1, 0);
986 #if !defined(ENABLE_SOFTFLOAT)
988 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
989 M_FST(s1, REG_ATMP1, 0);
992 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
993 M_DST(s1, REG_ATMP1, 0);
1000 case ICMD_GETFIELD: /* ... ==> ..., value */
1002 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1004 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1005 uf = iptr->sx.s23.s3.uf;
1006 fieldtype = uf->fieldref->parseddesc.fd->type;
1009 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1012 fi = iptr->sx.s23.s3.fmiref->p.field;
1013 fieldtype = fi->type;
1017 /* implicit null-pointer check */
1018 switch (fieldtype) {
1019 #if defined(ENABLE_SOFTFLOAT)
1023 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1026 #if defined(ENABLE_SOFTFLOAT)
1030 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1034 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1037 #if !defined(ENABLE_SOFTFLOAT)
1039 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1043 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_PUTFIELD: /* ..., value ==> ... */
1053 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1055 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1056 uf = iptr->sx.s23.s3.uf;
1057 fieldtype = uf->fieldref->parseddesc.fd->type;
1061 fi = iptr->sx.s23.s3.fmiref->p.field;
1062 fieldtype = fi->type;
1066 if (IS_INT_LNG_TYPE(fieldtype)) {
1067 if (IS_2_WORD_TYPE(fieldtype)) {
1068 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1070 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1073 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1076 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1077 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1079 /* implicit null-pointer check */
1080 switch (fieldtype) {
1081 #if defined(ENABLE_SOFTFLOAT)
1085 M_IST(s2, s1, disp);
1088 #if defined(ENABLE_SOFTFLOAT)
1092 M_LST(s2, s1, disp);
1095 M_AST(s2, s1, disp);
1097 #if !defined(ENABLE_SOFTFLOAT)
1099 M_FST(s2, s1, disp);
1102 M_DST(s2, s1, disp);
1108 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1110 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1111 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1112 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1113 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1114 M_INTMOVE(s2, REG_ITMP2);
1115 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1116 M_ADRMOVE(s1, REG_ATMP1);
1117 M_AADDINT(REG_ITMP2, REG_ATMP1);
1118 /* implicit null-pointer check */
1119 M_LBZX(REG_ATMP1, d);
1121 emit_store_dst(jd, iptr, d);
1124 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1126 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1127 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1128 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1129 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1130 M_INTMOVE(s2, REG_ITMP2);
1131 M_ISSL_IMM(1, REG_ITMP2);
1132 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1133 M_ADRMOVE(s1, REG_ATMP1);
1134 M_AADDINT(REG_ITMP2, REG_ATMP1);
1135 /* implicit null-pointer check */
1136 M_LHZX(REG_ATMP1, d);
1138 emit_store_dst(jd, iptr, d);
1141 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1143 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1144 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1145 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1146 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1147 M_INTMOVE(s2, REG_ITMP2);
1148 M_ISSL_IMM(1, REG_ITMP2);
1149 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1150 M_ADRMOVE(s1, REG_ATMP1);
1151 M_AADDINT(REG_ITMP2, REG_ATMP1);
1153 /* implicit null-pointer check */
1154 M_LHZX(REG_ATMP1, d);
1156 emit_store_dst(jd, iptr, d);
1159 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1161 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1162 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1163 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1164 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1165 M_INTMOVE(s2, REG_ITMP2);
1166 M_ISSL_IMM(2, REG_ITMP2);
1167 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1168 M_ADRMOVE(s1, REG_ATMP1);
1169 M_AADDINT(REG_ITMP2, REG_ATMP1);
1170 /* implicit null-pointer check */
1171 M_LWZX(REG_ATMP1, d);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1176 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1177 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1178 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1179 /* implicit null-pointer check */
1180 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1181 M_INTMOVE(s2, REG_ITMP1);
1182 M_ISSL_IMM(3, REG_ITMP1);
1183 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1184 M_ADRMOVE(s1, REG_ATMP1);
1185 M_AADDINT(REG_ITMP1, REG_ATMP1);
1186 /* implicit null-pointer check */
1187 M_LLD(d, REG_ATMP1, 0);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1192 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1193 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1194 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1195 M_INTMOVE(s2, REG_ITMP2);
1196 M_ISSL_IMM(2, REG_ITMP2);
1197 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1198 M_ADRMOVE(s1, REG_ATMP1);
1199 M_AADDINT(REG_ITMP2, REG_ATMP1);
1200 /* implicit null-pointer check */
1201 #if !defined(ENABLE_SOFTFLOAT)
1202 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1203 M_FLD(d, REG_ATMP1, 0);
1205 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1206 M_LWZX(REG_ATMP1, d);
1208 emit_store_dst(jd, iptr, d);
1211 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1212 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1213 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1214 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1215 M_INTMOVE(s2, REG_ITMP2);
1216 M_ISSL_IMM(3, REG_ITMP2);
1217 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1218 M_ADRMOVE(s1, REG_ATMP1);
1219 M_AADDINT(REG_ITMP2, REG_ATMP1);
1220 /* implicit null-pointer check */
1221 #if !defined(ENABLE_SOFTFLOAT)
1222 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1223 M_DLD(d, REG_ATMP1, 0);
1225 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1226 M_LLD(d, REG_ATMP1, 0);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1232 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1234 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1235 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1236 M_INTMOVE(s2, REG_ITMP2);
1237 M_ISSL_IMM(2, REG_ITMP2);
1238 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1239 M_ADRMOVE(s1, REG_ATMP1);
1240 M_AADDINT(REG_ITMP2, REG_ATMP1);
1242 /* implicit null-pointer check */
1243 M_LAX(REG_ATMP1, d);
1244 emit_store_dst(jd, iptr, d);
1248 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1249 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1250 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1251 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1252 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1253 M_INTMOVE(s2, REG_ITMP2);
1254 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1255 M_ADRMOVE(s1, REG_ATMP1);
1256 M_AADDINT(REG_ITMP2, REG_ATMP1);
1257 /* implicit null-pointer check */
1258 M_STBX(REG_ATMP1, s3);
1261 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1264 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1265 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1266 M_INTMOVE(s2, REG_ITMP2);
1267 M_ISSL_IMM(1, REG_ITMP2);
1268 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1269 M_ADRMOVE(s1, REG_ATMP1);
1270 M_AADDINT(REG_ITMP2, REG_ATMP1);
1271 /* implicit null-pointer check */
1272 M_STHX(REG_ATMP1, s3);
1275 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1276 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1277 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1278 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1279 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1280 M_INTMOVE(s2, REG_ITMP2);
1281 M_ISSL_IMM(1, REG_ITMP2);
1282 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1283 M_ADRMOVE(s1, REG_ATMP1);
1284 M_AADDINT(REG_ITMP2, REG_ATMP1);
1285 /* implicit null-pointer check */
1286 M_STHX(REG_ATMP1, s3);
1289 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1291 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1292 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1293 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1294 M_INTMOVE(s2, REG_ITMP2);
1295 M_ISSL_IMM(2, REG_ITMP2);
1296 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1297 M_ADRMOVE(s1, REG_ATMP1);
1298 M_AADDINT(REG_ITMP2, REG_ATMP1);
1299 /* implicit null-pointer check */
1300 M_STWX(REG_ATMP1, s3);
1303 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1304 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1305 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1306 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1308 M_INTMOVE(s2, REG_ITMP1);
1309 M_ISSL_IMM(3, REG_ITMP1);
1310 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1311 M_ADRMOVE(s1, REG_ATMP1);
1312 M_AADDINT(REG_ITMP1, REG_ATMP1);
1313 /* implicit null-pointer check */
1314 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1315 M_LST(s3, REG_ATMP1, 0);
1318 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1321 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1322 M_INTMOVE(s2, REG_ITMP2);
1323 M_ISSL_IMM(2, REG_ITMP2);
1324 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1325 M_ADRMOVE(s1, REG_ATMP1);
1326 M_AADDINT(REG_ITMP2, REG_ATMP1);
1327 /* implicit null-pointer check */
1328 #if !defined(ENABLE_SOFTFLOAT)
1329 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1330 M_FST(s3, REG_ATMP1, 0);
1332 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1333 M_STWX(REG_ATMP1, s3);
1337 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1341 M_INTMOVE(s2, REG_ITMP2);
1342 M_ISSL_IMM(3, REG_ITMP2);
1343 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1344 M_ADRMOVE(s1, REG_ATMP1);
1345 M_AADDINT(REG_ITMP2, REG_ATMP1);
1346 /* implicit null-pointer check */
1347 #if !defined(ENABLE_SOFTFLOAT)
1348 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1349 M_DST(s3, REG_ATMP1, 0);
1351 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1352 /* implicit null-pointer check */
1353 M_LST(s3, REG_ATMP1, 0);
1357 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1359 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1360 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1361 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1362 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1364 /* XXX what if array is NULL */
1365 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1367 M_AST(s1, REG_SP, 0*4);
1368 M_AST(s3, REG_SP, 1*4);
1369 M_JSR_IMM(BUILTIN_FAST_canstore);
1370 emit_arraystore_check(cd, iptr);
1372 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1373 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1374 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1375 M_INTMOVE(s2, REG_ITMP1);
1376 M_ISSL_IMM(2, REG_ITMP1);
1377 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1378 M_ADRMOVE(s1, REG_ATMP1);
1379 M_AADDINT(REG_ITMP1, REG_ATMP1);
1380 /* implicit null-pointer check */
1381 M_STAX(REG_ATMP1, s3);
1386 /* METHOD INVOCATION *********************************************************/
1387 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1388 bte = iptr->sx.s23.s3.bte;
1389 if (bte->stub == NULL)
1390 disp = (ptrint) bte->fp;
1392 disp = (ptrint) bte->stub;
1396 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1397 /* adress register for sure */
1398 M_ALD(REG_ATMP1, REG_SP, 0);
1399 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1402 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1403 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1404 um = iptr->sx.s23.s3.um;
1405 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um, 0);
1407 M_AMOV_IMM(disp, REG_ATMP1);
1409 lm = iptr->sx.s23.s3.fmiref->p.method;
1410 disp = lm->stubroutine;
1411 M_AMOV_IMM(disp, REG_ATMP1);
1414 /* generate the actual call */
1418 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1419 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1420 um = iptr->sx.s23.s3.um;
1421 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
1424 lm = iptr->sx.s23.s3.fmiref->p.method;
1425 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1427 /* load object pointer (==argument 0) */
1428 M_ALD(REG_ATMP1, REG_SP, 0);
1429 /* implicit null-pointer check */
1430 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1431 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1432 /* generate the actual call */
1436 case ICMD_INVOKEINTERFACE:
1437 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1438 um = iptr->sx.s23.s3.um;
1439 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
1444 lm = iptr->sx.s23.s3.fmiref->p.method;
1445 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
1446 s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
1448 /* load object pointer (==argument 0) */
1449 M_ALD(REG_ATMP1, REG_SP, 0);
1451 /* implicit null-pointer check */
1452 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1453 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1454 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1456 /* generate the actual call */
1464 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1465 /* all stuff is returned in %d0 */
1466 M_INT2ADRMOVE(REG_RESULT, s1);
1468 #if !defined(ENABLE_SOFTFLOAT)
1470 * for BUILTINS float values are returned in %d0,%d1
1471 * within cacao we use %fp0 for that.
1474 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1475 if (iptr->opc == ICMD_BUILTIN) {
1476 M_INT2FLTMOVE(REG_FRESULT, s1);
1478 emit_fmove(cd, REG_FRESULT, s1);
1482 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1483 if (iptr->opc == ICMD_BUILTIN) {
1484 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1485 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1487 emit_dmove(cd, REG_FRESULT, s1);
1496 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1497 /* val.a: (classinfo*) superclass */
1499 /* superclass is an interface:
1501 * return (sub != NULL) &&
1502 * (sub->vftbl->interfacetablelength > super->index) &&
1503 * (sub->vftbl->interfacetable[-super->index] != NULL);
1505 * superclass is a class:
1507 * return ((sub != NULL) && (0
1508 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1509 * super->vftbl->diffvall));
1516 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1521 super = iptr->sx.s23.s3.c.cls;
1522 superindex = super->index;
1525 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1528 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
1529 assert(VAROP(iptr->dst)->type == TYPE_INT);
1533 /* if class is not resolved, check which code to call */
1535 if (super == NULL) {
1537 emit_label_beq(cd, BRANCH_LABEL_1);
1539 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1541 M_IMOV_IMM32(0, REG_ITMP3);
1542 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
1543 emit_label_beq(cd, BRANCH_LABEL_2);
1546 /* interface instanceof code */
1548 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1549 if (super == NULL) {
1550 patcher_add_patch_ref(jd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
1553 emit_label_beq(cd, BRANCH_LABEL_3);
1556 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
1557 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
1558 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
1561 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
1567 emit_label_br(cd, BRANCH_LABEL_4);
1569 emit_label(cd, BRANCH_LABEL_3);
1572 /* class instanceof code */
1574 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1575 if (super == NULL) {
1576 emit_label(cd, BRANCH_LABEL_2);
1578 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1579 M_AMOV_IMM(0, REG_ATMP2);
1581 M_AMOV_IMM(super->vftbl, REG_ATMP2);
1583 emit_label_beq(cd, BRANCH_LABEL_5);
1586 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
1588 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
1589 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
1590 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
1592 M_ISUB(REG_ITMP3, REG_ITMP1);
1593 M_ICMP(REG_ITMP2, REG_ITMP1);
1596 M_TPFW; /* overlaps next instruction */
1600 emit_label(cd, BRANCH_LABEL_5);
1603 if (super == NULL) {
1604 emit_label(cd, BRANCH_LABEL_1);
1605 emit_label(cd, BRANCH_LABEL_4);
1608 emit_store_dst(jd, iptr, d);
1612 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1613 /* val.a: (classinfo*) superclass */
1615 /* superclass is an interface:
1617 * OK if ((sub == NULL) ||
1618 * (sub->vftbl->interfacetablelength > super->index) &&
1619 * (sub->vftbl->interfacetable[-super->index] != NULL));
1621 * superclass is a class:
1623 * OK if ((sub == NULL) || (0
1624 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1625 * super->vftbl->diffvall));
1628 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
1629 /* object type cast-check */
1634 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1639 super = iptr->sx.s23.s3.c.cls;
1640 superindex = super->index;
1643 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1644 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1646 /* if class is not resolved, check which code to call */
1648 if (super == NULL) {
1650 emit_label_beq(cd, BRANCH_LABEL_1);
1652 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
1654 M_IMOV_IMM32(0, REG_ITMP2);
1655 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
1656 emit_label_beq(cd, BRANCH_LABEL_2);
1659 /* interface checkcast code */
1661 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
1662 if (super == NULL) {
1663 patcher_add_patch_ref(jd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
1666 emit_label_beq(cd, BRANCH_LABEL_3);
1669 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
1670 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
1672 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
1674 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
1676 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
1678 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
1681 emit_label_br(cd, BRANCH_LABEL_4);
1683 emit_label(cd, BRANCH_LABEL_3);
1686 /* class checkcast code */
1688 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
1689 if (super == NULL) {
1690 emit_label(cd, BRANCH_LABEL_2);
1692 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
1693 M_AMOV_IMM(0, REG_ATMP3);
1695 M_AMOV_IMM(super->vftbl, REG_ATMP3);
1697 emit_label_beq(cd, BRANCH_LABEL_5);
1700 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
1702 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
1703 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
1704 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
1706 M_ISUB(REG_ITMP1, REG_ITMP3);
1707 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
1709 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
1712 emit_label(cd, BRANCH_LABEL_5);
1715 if (super == NULL) {
1716 emit_label(cd, BRANCH_LABEL_1);
1717 emit_label(cd, BRANCH_LABEL_4);
1720 d = codegen_reg_of_dst(jd, iptr, s1);
1722 /* array type cast-check */
1724 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
1726 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1727 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
1728 M_AMOV_IMM(0, REG_ATMP1);
1730 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
1735 M_JSR_IMM(BUILTIN_arraycheckcast);
1736 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
1738 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
1740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1741 d = codegen_reg_of_dst(jd, iptr, s1);
1743 assert(VAROP(iptr->dst)->type == TYPE_ADR);
1745 emit_store_dst(jd, iptr, d);
1748 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1751 branch_target_t *table;
1753 table = iptr->dst.table;
1755 l = iptr->sx.s23.s2.tablelow;
1756 i = iptr->sx.s23.s3.tablehigh;
1758 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1759 M_INTMOVE(s1, REG_ITMP1);
1760 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
1765 M_ICMP_IMM(i - 1, REG_ITMP1);
1766 emit_bugt(cd, table[0].block);
1768 /* build jump table top down and use address of lowest entry */
1772 dseg_add_target(cd, table->block);
1776 /* length of dataseg after last dseg_add_target is used by load */
1777 M_AMOV_IMM(0, REG_ATMP2);
1780 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
1781 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
1782 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
1783 M_ALD(REG_ATMP1, REG_ATMP2, 0);
1790 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1792 /* check for negative sizes and copy sizes to stack if necessary */
1793 MCODECHECK((iptr->s1.argcount << 1) + 64);
1795 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
1796 var = VAR(iptr->sx.s23.s2.args[s1]);
1798 /* Already Preallocated? */
1799 if (!(var->flags & PREALLOC)) {
1800 s2 = emit_load(jd, iptr, var, REG_ITMP1);
1801 M_IST(s2, REG_SP, (s1 + 3) * 4);
1805 /* a0 = dimension count */
1806 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
1807 M_IST(REG_ITMP1, REG_SP, 0*4);
1809 /* a1 = arraydescriptor */
1810 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1811 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
1812 M_AMOV_IMM(0, REG_ATMP1);
1814 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
1816 M_AST(REG_ATMP1, REG_SP, 1*4);
1818 /* a2 = pointer to dimensions = stack pointer */
1819 M_AMOV(REG_SP, REG_ATMP1);
1820 M_AADD_IMM(3*4, REG_ATMP1);
1821 M_AST(REG_ATMP1, REG_SP, 2*4);
1823 M_JSR_IMM(BUILTIN_multianewarray);
1825 /* check for exception before result assignment */
1826 emit_exception_check(cd, iptr);
1828 assert(VAROP(iptr->dst)->type == TYPE_ADR);
1829 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1830 M_INT2ADRMOVE(REG_RESULT, d);
1831 emit_store_dst(jd, iptr, d);
1837 vm_abort("Unknown ICMD %d during code generation", iptr->opc);
1842 /* codegen_emit_stub_native ****************************************************
1844 Emits a stub routine which calls a native method.
1846 *******************************************************************************/
1848 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
1857 /* get required compiler data */
1866 /* calc stackframe size */
1867 cd->stackframesize =
1868 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
1869 sizeof(localref_table) / SIZEOF_VOID_P +
1871 1 + /* functionptr */
1872 4; /* args for codegen_start_native_call */
1874 /* create method header */
1875 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
1876 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
1877 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
1878 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
1879 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
1882 M_AADD_IMM(-(cd->stackframesize*8), REG_SP);
1884 /* put arguments for codegen_start_native_call onto stack */
1885 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
1887 M_AMOV(REG_SP, REG_ATMP1);
1888 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
1890 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
1891 dseg_adddata(cd); /* this patches it */
1893 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
1895 M_JSR_IMM(codegen_start_native_call);
1897 /* remember class argument */
1898 if (m->flags & ACC_STATIC)
1899 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
1901 /* copy arguments into stackframe */
1902 for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) {
1903 t = md->paramtypes[i].type;
1904 /* all arguments via stack */
1905 assert(md->params[i].inmemory);
1907 s1 = md->params[i].regoff + cd->stackframesize * 8 + 4;
1908 s2 = nmd->params[j].regoff;
1910 /* simply copy argument stack */
1911 M_ILD(REG_ITMP1, REG_SP, s1);
1912 M_IST(REG_ITMP1, REG_SP, s2);
1913 if (IS_2_WORD_TYPE(t)) {
1914 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
1915 M_IST(REG_ITMP1, REG_SP, s2 + 4);
1919 /* builtins are not invoked like natives, environemtn and clazz are only needed for natives */
1920 if (m->flags & ACC_NATIVE) {
1921 /* for static function class as second arg */
1922 if (m->flags & ACC_STATIC)
1923 M_AST(REG_ATMP3, REG_SP, 1 * 4);
1925 /* env ist first argument */
1926 M_AMOV_IMM(VM_get_jnienv(), REG_ATMP1);
1927 M_AST(REG_ATMP1, REG_SP, 0 * 4);
1930 /* call the native function */
1931 M_AMOV_IMM(f, REG_ATMP2);
1934 /* save return value */
1935 switch (md->returntype.type) {
1936 case TYPE_VOID: break;
1938 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
1941 M_IST(REG_D1, REG_SP, 2 * 8);
1947 M_IST(REG_D0, REG_SP, 2 * 8); /* XXX can this be correct ? */
1953 /* remove native stackframe info */
1954 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
1956 M_AMOV(REG_SP, REG_ATMP1);
1957 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
1959 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
1960 dseg_adddata(cd); /* this patches it */
1962 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
1964 M_JSR_IMM(codegen_finish_native_call);
1966 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
1967 /* restore return value */
1968 switch (md->returntype.type) {
1969 case TYPE_VOID: break;
1972 case TYPE_LNG: M_ILD(REG_D1, REG_SP, 2 * 8);
1977 M_ILD(REG_D0, REG_SP, 2 * 8); /* XXX */
1982 #if !defined(ENABLE_SOFTFLOAT)
1983 /* additionally load values into floating points registers
1984 * as cacao jit code expects them there */
1985 switch (md->returntype.type) {
1987 M_FLD(REG_D0, REG_SP, 2 * 8);
1990 M_DLD(REG_D0, REG_SP, 2 * 8); /* XXX */
1994 /* restore saved registers */
1996 M_AADD_IMM(cd->stackframesize*8, REG_SP);
1997 /* check for exception */
2002 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2004 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2005 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2006 M_JMP_IMM(asm_handle_nat_exception);
2008 /* should never be reached from within jit code*/
2014 * These are local overrides for various environment variables in Emacs.
2015 * Please do not remove this and leave it at the end of the file, where
2016 * Emacs will automagically detect them.
2017 * ---------------------------------------------------------------------
2020 * indent-tabs-mode: t
2024 * vim:noexpandtab:sw=4:ts=4: