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 $
39 #include "vm/jit/m68k/codegen.h"
40 #include "vm/jit/m68k/emit.h"
42 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/localref.h"
45 #include "native/native.h"
47 #include "threads/lock-common.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
52 #include "vm/stringlocal.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/dseg.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/parse.h"
61 #include "vm/jit/patcher.h"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.h"
64 #include "vm/jit/stacktrace.h"
65 #include "vm/jit/md.h"
67 #include "vmcore/loader.h"
68 #include "vmcore/options.h"
69 #include "vmcore/utf8.h"
72 bool codegen_emit(jitdata *jd)
78 s4 len, s1, s2, s3, d, disp;
85 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
86 unresolved_method *um;
87 builtintable_entry *bte;
94 /* get required compiler data */
101 /* prevent compiler warnings */
109 /* save calle saved registers */
110 s4 savedregs_num = 0;
112 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
113 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
114 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
116 cd->stackframesize = rd->memuse + savedregs_num;
118 /* we always add 2 stack slots.
119 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
120 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
121 * on the other hand we could use 2 words when a builtin returns a doulbe which are
122 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
123 * so we always _need_ at least 2 slots, and this keeps the code simple */
124 cd->stackframesize += 2;
126 cd->stackframesize *= 8; /* we use 8 byte stack slots */
129 #if defined(ENABLE_THREADS)
130 /* we need additional space to save argument of monitor_enter */
131 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
132 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
133 cd->stackframesize += 2;
135 cd->stackframesize += 1;
141 /* create method header */
142 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
143 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
144 #if defined(ENABLE_THREADS)
145 if (checksync && (m->flags & ACC_SYNCHRONIZED))
146 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8);/* IsSync */
149 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
150 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
152 /* XXX we use the IntSave a split field for the adr now */
153 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
154 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
156 dseg_addlinenumbertablesize(cd);
158 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
160 /* create exception table */
161 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
162 dseg_add_target(cd, ex->start);
163 dseg_add_target(cd, ex->end);
164 dseg_add_target(cd, ex->handler);
165 (void) dseg_add_unique_address(cd, ex->catchtype.any);
168 #if defined(ENABLE_PROFILING)
173 emit_verbosecall_enter(jd);
175 /* create stack frame */
176 M_AADD_IMM(-(cd->stackframesize), REG_SP);
178 /* save used callee saved registers */
179 p = cd->stackframesize;
180 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
181 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
183 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
184 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
186 #if !defined(ENABLE_SOFTFLOAT)
187 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
188 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
191 assert(FLT_SAV_CNT == 0);
192 assert(rd->savfltreguse == 0);
194 /* take arguments out of stack frame */
196 for (p = 0, l = 0; p < md->paramcount; p++) {
197 t = md->paramtypes[p].type;
198 varindex = jd->local_map[l * 5 + t];
201 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
204 if (varindex == UNUSED)
209 s1 = md->params[p].regoff;
210 assert(md->params[p].inmemory); /* all args are on stack */
213 #if defined(ENABLE_SOFTFLOAT)
219 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
220 if (IS_2_WORD_TYPE(t)) {
221 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
223 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
225 } else { /* stack arg -> spilled */
226 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
227 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
228 if (IS_2_WORD_TYPE(t)) {
229 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
230 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
234 #if !defined(ENABLE_SOFTFLOAT)
237 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
238 if (IS_2_WORD_TYPE(t)) {
239 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
241 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
243 } else { /* stack-arg -> spilled */
244 if (IS_2_WORD_TYPE(t)) {
245 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
246 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
248 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
249 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
253 #endif /* SOFTFLOAT */
255 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
256 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
257 } else { /* stack-arg -> spilled */
258 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
259 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
264 } /* end for argument out of stack*/
266 #if defined(ENABLE_THREADS)
267 /* call lock_monitor_enter function */
268 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
269 if (m->flags & ACC_STATIC) {
270 M_AMOV_IMM((&m->class->object.header), REG_ATMP1);
272 /* for non-static case the first arg is the object */
273 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
276 M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
279 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
280 M_AST(REG_ATMP1, REG_SP, 0 * 4);
281 M_JSR_IMM(LOCK_monitor_enter);
287 /* create replacement points */
288 REPLACEMENT_POINTS_INIT(cd, jd);
290 /* foreach basic block */
291 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
293 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
295 if (bptr->flags >= BBREACHED) {
297 /* branch resolving */
298 codegen_resolve_branchrefs(cd, bptr);
300 /* handle replacement points */
301 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
303 #if defined(ENABLE_PROFILING)
306 /* FIXME there are still some constrcuts to copy in here */
308 #if defined(ENABLE_LSRA)
312 /* copy interface registers to their destination */
318 var = VAR(bptr->invars[len]);
319 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
320 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
321 M_ADRMOVE(REG_ATMP1_XPTR, d);
322 emit_store(jd, NULL, var, d);
325 assert((var->flags & INOUT));
329 /* walk through all instructions */
333 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
334 if (iptr->line != currentline) {
335 dseg_addlinenumber(cd, iptr->line);
336 currentline = iptr->line;
339 MCODECHECK(1024); /* 1kB should be enough */
342 case ICMD_NOP: /* ... ==> ... */
343 case ICMD_POP: /* ..., value ==> ... */
344 case ICMD_POP2: /* ..., value, value ==> ... */
347 case ICMD_INLINE_START:
349 REPLACEMENT_POINT_INLINE_START(cd, iptr);
352 case ICMD_INLINE_BODY:
354 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
355 dseg_addlinenumber_inline_start(cd, iptr);
356 dseg_addlinenumber(cd, iptr->line);
359 case ICMD_INLINE_END:
361 dseg_addlinenumber_inline_end(cd, iptr);
362 dseg_addlinenumber(cd, iptr->line);
365 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
368 assert(VAROP(iptr->s1)->type == TYPE_ADR);
369 emit_nullpointer_check(cd, iptr, s1);
373 /* CONST **************************************************************/
374 case ICMD_ICONST: /* ... ==> ..., constant */
375 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
376 M_IMOV_IMM(iptr->sx.val.i, d);
377 emit_store_dst(jd, iptr, d);
380 case ICMD_LCONST: /* ... ==> ..., constant */
382 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
383 LCONST(iptr->sx.val.l, d);
384 emit_store_dst(jd, iptr, d);
387 case ICMD_FCONST: /* ... ==> ..., constant */
389 #if defined(ENABLE_SOFTFLOAT)
390 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
391 M_IMOV_IMM(iptr->sx.val.i, d);
392 emit_store_dst(jd, iptr, d);
394 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
395 FCONST(iptr->sx.val.i, d);
396 emit_store_dst(jd, iptr, d);
400 case ICMD_DCONST: /* ... ==> ..., constant */
402 #if defined(ENABLE_SOFTFLOAT)
403 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
404 LCONST(iptr->sx.val.l, d);
405 emit_store_dst(jd, iptr, d);
407 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
408 disp = dseg_add_double(cd, iptr->sx.val.d);
409 M_AMOV_IMM(0, REG_ATMP1);
411 M_DLD(d, REG_ATMP1, disp);
412 emit_store_dst(jd, iptr, d);
417 /* some long operations *********************************************/
418 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
419 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
420 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
421 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
422 M_INTMOVE(s2, REG_ITMP1);
423 M_IADD(s1, REG_ITMP1); /* low word */
424 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
425 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
426 M_INTMOVE(s2, REG_ITMP2);
427 M_IADDX(s1, REG_ITMP2); /* high word */
428 emit_store_dst(jd, iptr, d);
431 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
432 /* sx.val.l = constant */
433 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
434 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
435 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
437 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
439 s3 = iptr->sx.val.l & 0xffffffff;
440 M_INTMOVE(s1, REG_ITMP1);
441 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
443 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
444 M_LNGMOVE(REG_ITMP12_PACKED, d);
445 emit_store_dst(jd, iptr, d);
448 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
449 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
450 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
451 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
452 M_INTMOVE(s1, REG_ITMP1);
453 M_ISUB(s2, REG_ITMP1); /* low word */
454 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
455 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
456 M_INTMOVE(s1, REG_ITMP2);
457 M_ISUBX(s2, REG_ITMP2); /* high word */
458 emit_store_dst(jd, iptr, d);
461 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
462 /* sx.val.l = constant */
463 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
464 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
465 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
467 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
469 s3 = (-iptr->sx.val.l) & 0xffffffff;
470 M_INTMOVE(s1, REG_ITMP1);
471 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
473 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
474 M_LNGMOVE(REG_ITMP12_PACKED, d);
475 emit_store_dst(jd, iptr, d);
478 case ICMD_LNEG: /* ..., value ==> ..., - value */
479 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
481 M_LNGMOVE(s1, REG_ITMP12_PACKED);
482 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
483 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
484 M_LNGMOVE(REG_ITMP12_PACKED, d);
485 emit_store_dst(jd, iptr, d);
488 /* integer operations ************************************************/
489 case ICMD_INEG: /* ..., value ==> ..., - value */
491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
492 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
493 M_INTMOVE(s1, REG_ITMP1);
495 M_INTMOVE(REG_ITMP1, d);
496 emit_store_dst(jd, iptr, d);
499 case ICMD_I2L: /* ..., value ==> ..., value */
501 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
502 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
503 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
505 M_ISET(GET_HIGH_REG(d));
507 M_ICLR(GET_HIGH_REG(d));
509 emit_store_dst(jd, iptr, d);
512 case ICMD_L2I: /* ..., value ==> ..., value */
514 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
517 emit_store_dst(jd, iptr, d);
519 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
524 emit_store_dst(jd, iptr, d);
527 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
532 emit_store_dst(jd, iptr, d);
535 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
538 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
540 emit_store_dst(jd, iptr, d);
545 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
548 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
549 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
550 M_INTMOVE(s2, REG_ITMP2);
551 M_IADD(s1, REG_ITMP2);
552 M_INTMOVE(REG_ITMP2, d);
553 emit_store_dst(jd, iptr, d);
556 /* s1.localindex = variable, sx.val.i = constant*/
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
563 M_INTMOVE(s1, REG_ITMP1);
564 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
565 M_INTMOVE(REG_ITMP1, d);
566 emit_store_dst(jd, iptr, d);
569 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
573 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
574 M_INTMOVE(s1, REG_ITMP1);
575 M_ISUB(s2, REG_ITMP1);
576 M_INTMOVE(REG_ITMP1, d);
577 emit_store_dst(jd, iptr, d);
580 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
581 /* sx.val.i = constant */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
585 M_INTMOVE(s1, REG_ITMP1);
586 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
587 M_INTMOVE(REG_ITMP1, d);
588 emit_store_dst(jd, iptr, d);
591 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
593 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
595 emit_arithmetic_check(cd, iptr, s2);
596 M_INTMOVE(s1, REG_ITMP1);
597 M_IDIV(s2, REG_ITMP1);
598 M_INTMOVE(REG_ITMP1, d);
599 emit_store_dst(jd, iptr, d);
602 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
605 M_INTMOVE(s1, REG_ITMP1);
609 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
611 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
612 M_ISSR(REG_ITMP2, REG_ITMP1);
613 M_INTMOVE(REG_ITMP1, d);
614 emit_store_dst(jd, iptr, d);
617 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
620 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
621 emit_arithmetic_check(cd, iptr, s2);
623 M_ICMP_IMM(0x80000000, s1);
628 M_TPFL; /* hides the next instruction */
629 M_IREM(s2, s1, REG_ITMP3);
631 M_INTMOVE(REG_ITMP3, d);
633 emit_store_dst(jd, iptr, d);
636 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
640 M_IMOV(s1, REG_ITMP1);
644 M_IAND_IMM(iptr->sx.val.i, d);
646 M_BGE(2 + 2 + 6 + 2);
647 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
649 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
652 emit_store_dst(jd, iptr, d);
656 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
657 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
659 bte = iptr->sx.s23.s3.bte;
662 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
663 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
664 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
665 /* XXX could be optimized */
666 emit_arithmetic_check(cd, iptr, REG_ITMP3);
668 M_LST(s2, REG_SP, 2 * 4);
669 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
670 M_LST(s1, REG_SP, 0 * 4);
674 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
675 M_LNGMOVE(REG_RESULT_PACKED, d);
676 emit_store_dst(jd, iptr, d);
679 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
681 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
682 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 M_INTMOVE(s2, REG_ITMP2);
685 M_IMUL(s1, REG_ITMP2);
686 M_INTMOVE(REG_ITMP2, d);
687 emit_store_dst(jd, iptr, d);
690 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
691 /* sx.val.i = constant */
692 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
693 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
694 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
695 M_IMUL(s1, REG_ITMP2);
696 M_INTMOVE(REG_ITMP2, d);
697 emit_store_dst(jd, iptr, d);
700 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
703 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
705 M_INTMOVE(s1, REG_ITMP1);
706 M_INTMOVE(s2, REG_ITMP2);
707 M_IAND_IMM(0x1f, REG_ITMP2);
708 M_ISSL(REG_ITMP2, REG_ITMP1);
709 M_INTMOVE(REG_ITMP1, d);
710 emit_store_dst(jd, iptr, d);
713 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
714 /* sx.val.i = constant */
716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
718 if (iptr->sx.val.i & 0x1f) {
719 M_INTMOVE(s1, REG_ITMP1)
720 if ((iptr->sx.val.i & 0x1f) <= 7) {
721 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
723 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
724 M_ISSL(REG_ITMP2, REG_ITMP1);
726 M_INTMOVE(REG_ITMP1, d);
730 emit_store_dst(jd, iptr, d);
733 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
735 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
736 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
737 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
738 M_INTMOVE(s1, REG_ITMP1);
739 M_INTMOVE(s2, REG_ITMP2);
740 M_IAND_IMM(0x1f, REG_ITMP2);
741 M_ISSR(REG_ITMP2, REG_ITMP1);
742 M_INTMOVE(REG_ITMP1, d);
743 emit_store_dst(jd, iptr, d);
746 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
747 /* sx.val.i = constant */
749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
751 if (iptr->sx.val.i & 0x1f) {
752 M_INTMOVE(s1, REG_ITMP1)
753 if ((iptr->sx.val.i & 0x1f) <= 7) {
754 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
756 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
757 M_ISSR(REG_ITMP2, REG_ITMP1);
759 M_INTMOVE(REG_ITMP1, d);
763 emit_store_dst(jd, iptr, d);
766 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
771 M_INTMOVE(s1, REG_ITMP1);
772 M_INTMOVE(s2, REG_ITMP2);
773 M_IAND_IMM(0x1f, REG_ITMP2);
774 M_IUSR(REG_ITMP2, REG_ITMP1);
775 M_INTMOVE(REG_ITMP1, d);
776 emit_store_dst(jd, iptr, d);
779 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
780 /* sx.val.i = constant */
781 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
783 if (iptr->sx.val.i & 0x1f) {
784 M_INTMOVE(s1, REG_ITMP1)
785 if ((iptr->sx.val.i & 0x1f) <= 7) {
786 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
788 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
789 M_IUSR(REG_ITMP2, REG_ITMP1);
791 M_INTMOVE(REG_ITMP1, d);
795 emit_store_dst(jd, iptr, d);
798 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
802 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
803 M_INTMOVE(s2, REG_ITMP2);
804 M_IAND(s1, REG_ITMP2);
805 M_INTMOVE(REG_ITMP2, d);
806 emit_store_dst(jd, iptr, d);
809 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
810 /* sx.val.i = constant */
812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
814 M_INTMOVE(s1, REG_ITMP1);
815 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
816 M_INTMOVE(REG_ITMP1, d);
817 emit_store_dst(jd, iptr, d);
820 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
822 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
823 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 M_INTMOVE(s2, REG_ITMP2);
825 M_IOR(s1, REG_ITMP2);
826 M_INTMOVE(REG_ITMP2, d);
827 emit_store_dst(jd, iptr, d);
830 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
831 /* sx.val.i = constant */
832 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
834 M_INTMOVE(s1, REG_ITMP1);
835 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
836 M_INTMOVE(REG_ITMP1, d);
837 emit_store_dst(jd, iptr, d);
840 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
843 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
844 M_INTMOVE(s2, REG_ITMP2);
845 M_IXOR(s1, REG_ITMP2);
846 M_INTMOVE(REG_ITMP2, d);
847 emit_store_dst(jd, iptr, d);
850 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
851 /* sx.val.i = constant */
852 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
853 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
854 M_INTMOVE(s1, REG_ITMP1);
855 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
856 M_INTMOVE(REG_ITMP1, d);
857 emit_store_dst(jd, iptr, d);
860 /* floating point operations ******************************************/
861 #if !defined(ENABLE_SOFTFLOAT)
862 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
864 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
865 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
869 M_BFUN(14); /* result is -1, branch to end */
870 M_BFLT(10); /* result is -1, branch to end */
872 M_BFEQ(4) /* result is 0, branch to end */
874 emit_store_dst(jd, iptr, d);
877 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
879 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
880 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
881 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
884 M_BFUN(16); /* result is +1, branch to end */
885 M_BFGT(14); /* result is +1, branch to end */
887 M_BFEQ(8) /* result is 0, branch to end */
889 emit_store_dst(jd, iptr, d);
892 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
893 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
894 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
895 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
896 M_FLTMOVE(s2, REG_FTMP2);
897 M_FMUL(s1, REG_FTMP2);
898 M_FLTMOVE(REG_FTMP2, d);
899 emit_store_dst(jd, iptr, d);
902 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
903 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
904 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
905 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
906 M_DBLMOVE(s2, REG_FTMP2);
907 M_DMUL(s1, REG_FTMP2);
908 M_DBLMOVE(REG_FTMP2, d);
909 emit_store_dst(jd, iptr, d);
912 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
913 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
914 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
915 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
916 M_FLTMOVE(s1, REG_FTMP1);
917 M_FDIV(s2, REG_FTMP1);
918 M_FLTMOVE(REG_FTMP1, d);
919 emit_store_dst(jd, iptr, d);
922 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
923 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
924 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
925 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
926 M_DBLMOVE(s1, REG_FTMP1);
927 M_DDIV(s2, REG_FTMP1);
928 M_DBLMOVE(REG_FTMP1, d);
929 emit_store_dst(jd, iptr, d);
932 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
933 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
934 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
935 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
936 M_FLTMOVE(s2, REG_FTMP2);
937 M_FADD(s1, REG_FTMP2);
938 M_FLTMOVE(REG_FTMP2, d);
939 emit_store_dst(jd, iptr, d);
942 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
943 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
944 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
945 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
946 M_DBLMOVE(s2, REG_FTMP2);
947 M_DADD(s1, REG_FTMP2);
948 M_DBLMOVE(REG_FTMP2, d);
949 emit_store_dst(jd, iptr, d);
952 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
953 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
954 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
955 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
956 M_FLTMOVE(s1, REG_FTMP1);
957 M_FSUB(s2, REG_FTMP1);
958 M_FLTMOVE(REG_FTMP1, d);
959 emit_store_dst(jd, iptr, d);
962 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
963 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
964 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
965 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
966 M_DBLMOVE(s1, REG_FTMP1);
967 M_DSUB(s2, REG_FTMP1);
968 M_DBLMOVE(REG_FTMP1, d);
969 emit_store_dst(jd, iptr, d);
972 case ICMD_F2D: /* ..., value ==> ..., (double) value */
973 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
974 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
976 emit_store_dst(jd, iptr, d);
979 case ICMD_D2F: /* ..., value ==> ..., (float) value */
980 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
981 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
983 emit_store_dst(jd, iptr, d);
986 case ICMD_FNEG: /* ..., value ==> ..., - value */
987 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
988 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
990 emit_store_dst(jd, iptr, d);
993 case ICMD_DNEG: /* ..., value ==> ..., - value */
994 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
995 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
997 emit_store_dst(jd, iptr, d);
1002 /* load/store/copy/move operations ************************************/
1004 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
1005 case ICMD_ALOAD: /* s1 = local variable */
1009 case ICMD_ISTORE: /* ..., value ==> ... */
1016 emit_copy(jd, iptr);
1021 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1022 emit_copy(jd, iptr);
1026 case ICMD_ACONST: /* ... ==> ..., constant */
1027 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1029 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1030 constant_classref *cr = iptr->sx.val.c.ref;;
1031 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1034 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1036 emit_store_dst(jd, iptr, d);
1038 /* BRANCH *************************************************************/
1040 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1042 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1043 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1045 #ifdef ENABLE_VERIFIER
1046 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1047 unresolved_class *uc = iptr->sx.s23.s2.uc;
1049 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1051 #endif /* ENABLE_VERIFIER */
1052 M_JSR_PCREL(2); /* get current PC */
1055 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1060 case ICMD_GOTO: /* ... ==> ... */
1061 case ICMD_RET: /* ... ==> ... */
1063 emit_br(cd, iptr->dst.block);
1067 case ICMD_JSR: /* ... ==> ... */
1069 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1075 case ICMD_IFNULL: /* ..., value ==> ... */
1076 case ICMD_IFNONNULL:
1077 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1078 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1080 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1088 case ICMD_IFEQ: /* ..., value ==> ... */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 assert (VAROP(iptr->s1)->type == TYPE_INT);
1092 M_ICMP_IMM(iptr->sx.val.i, s1);
1093 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1096 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1097 case ICMD_IF_ICMPNE:
1098 case ICMD_IF_ICMPLT:
1099 case ICMD_IF_ICMPGT:
1100 case ICMD_IF_ICMPLE:
1101 case ICMD_IF_ICMPGE:
1103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1104 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1106 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1109 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1110 case ICMD_IF_ACMPNE:
1112 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1113 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1115 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1119 /* MEMORY *************************************************************/
1121 case ICMD_GETSTATIC: /* ... ==> ..., value */
1123 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1124 uf = iptr->sx.s23.s3.uf;
1125 fieldtype = uf->fieldref->parseddesc.fd->type;
1128 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1131 fi = iptr->sx.s23.s3.fmiref->p.field;
1132 fieldtype = fi->type;
1133 disp = (intptr_t) fi->value;
1135 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1136 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1141 M_AMOV_IMM(disp, REG_ATMP1);
1142 switch (fieldtype) {
1143 #if defined(ENABLE_SOFTFLOAT)
1147 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1148 M_ILD(d, REG_ATMP1, 0);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1152 M_ALD(d, REG_ATMP1, 0);
1154 #if defined(ENABLE_SOFTFLOAT)
1158 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1159 M_LLD(d, REG_ATMP1, 0);
1161 #if !defined(ENABLE_SOFTFLOAT)
1163 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1164 M_FLD(d, REG_ATMP1, 0);
1167 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1168 M_DLD(d, REG_ATMP1, 0);
1172 emit_store_dst(jd, iptr, d);
1175 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1177 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1178 uf = iptr->sx.s23.s3.uf;
1179 fieldtype = uf->fieldref->parseddesc.fd->type;
1182 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1185 fi = iptr->sx.s23.s3.fmiref->p.field;
1186 fieldtype = fi->type;
1187 disp = (intptr_t) fi->value;
1189 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1190 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1194 M_AMOV_IMM(disp, REG_ATMP1);
1195 switch (fieldtype) {
1196 #if defined(ENABLE_SOFTFLOAT)
1200 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1201 M_IST(s1, REG_ATMP1, 0);
1203 #if defined(ENABLE_SOFTFLOAT)
1207 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1208 M_LST(s1, REG_ATMP1, 0);
1211 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1212 M_AST(s1, REG_ATMP1, 0);
1214 #if !defined(ENABLE_SOFTFLOAT)
1216 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1217 M_FST(s1, REG_ATMP1, 0);
1220 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1221 M_DST(s1, REG_ATMP1, 0);
1228 case ICMD_GETFIELD: /* ... ==> ..., value */
1230 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1232 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1233 uf = iptr->sx.s23.s3.uf;
1234 fieldtype = uf->fieldref->parseddesc.fd->type;
1237 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1240 fi = iptr->sx.s23.s3.fmiref->p.field;
1241 fieldtype = fi->type;
1245 /* implicit null-pointer check */
1246 switch (fieldtype) {
1247 #if defined(ENABLE_SOFTFLOAT)
1251 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1254 #if defined(ENABLE_SOFTFLOAT)
1258 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1262 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1265 #if !defined(ENABLE_SOFTFLOAT)
1267 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1271 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1276 emit_store_dst(jd, iptr, d);
1279 case ICMD_PUTFIELD: /* ..., value ==> ... */
1281 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1283 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1284 uf = iptr->sx.s23.s3.uf;
1285 fieldtype = uf->fieldref->parseddesc.fd->type;
1289 fi = iptr->sx.s23.s3.fmiref->p.field;
1290 fieldtype = fi->type;
1294 if (IS_INT_LNG_TYPE(fieldtype)) {
1295 if (IS_2_WORD_TYPE(fieldtype)) {
1296 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1298 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1301 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1304 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1305 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1307 /* implicit null-pointer check */
1308 switch (fieldtype) {
1309 #if defined(ENABLE_SOFTFLOAT)
1313 M_IST(s2, s1, disp);
1316 #if defined(ENABLE_SOFTFLOAT)
1320 M_LST(s2, s1, disp);
1323 M_AST(s2, s1, disp);
1325 #if !defined(ENABLE_SOFTFLOAT)
1327 M_FST(s2, s1, disp);
1330 M_DST(s2, s1, disp);
1336 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1338 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1339 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1340 /* implicit null-pointer check */
1341 M_ILD(d, s1, OFFSET(java_array_t, size));
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1347 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1348 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1349 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1350 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1351 M_INTMOVE(s2, REG_ITMP2);
1352 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1353 M_ADRMOVE(s1, REG_ATMP1);
1354 M_AADDINT(REG_ITMP2, REG_ATMP1);
1355 /* implicit null-pointer check */
1356 M_LBZX(REG_ATMP1, d);
1358 emit_store_dst(jd, iptr, d);
1361 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1363 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1364 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1366 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1367 M_INTMOVE(s2, REG_ITMP2);
1368 M_ISSL_IMM(1, REG_ITMP2);
1369 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1370 M_ADRMOVE(s1, REG_ATMP1);
1371 M_AADDINT(REG_ITMP2, REG_ATMP1);
1372 /* implicit null-pointer check */
1373 M_LHZX(REG_ATMP1, d);
1375 emit_store_dst(jd, iptr, d);
1378 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1380 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1381 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1382 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1383 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1384 M_INTMOVE(s2, REG_ITMP2);
1385 M_ISSL_IMM(1, REG_ITMP2);
1386 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1387 M_ADRMOVE(s1, REG_ATMP1);
1388 M_AADDINT(REG_ITMP2, REG_ATMP1);
1390 /* implicit null-pointer check */
1391 M_LHZX(REG_ATMP1, d);
1393 emit_store_dst(jd, iptr, d);
1396 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1398 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1399 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1400 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1401 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1402 M_INTMOVE(s2, REG_ITMP2);
1403 M_ISSL_IMM(2, REG_ITMP2);
1404 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1405 M_ADRMOVE(s1, REG_ATMP1);
1406 M_AADDINT(REG_ITMP2, REG_ATMP1);
1407 /* implicit null-pointer check */
1408 M_LWZX(REG_ATMP1, d);
1409 emit_store_dst(jd, iptr, d);
1412 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1413 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1415 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1416 /* implicit null-pointer check */
1417 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1418 M_INTMOVE(s2, REG_ITMP1);
1419 M_ISSL_IMM(3, REG_ITMP1);
1420 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1421 M_ADRMOVE(s1, REG_ATMP1);
1422 M_AADDINT(REG_ITMP1, REG_ATMP1);
1423 /* implicit null-pointer check */
1424 M_LLD(d, REG_ATMP1, 0);
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1429 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1430 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1431 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1432 M_INTMOVE(s2, REG_ITMP2);
1433 M_ISSL_IMM(2, REG_ITMP2);
1434 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1435 M_ADRMOVE(s1, REG_ATMP1);
1436 M_AADDINT(REG_ITMP2, REG_ATMP1);
1437 /* implicit null-pointer check */
1438 #if !defined(ENABLE_SOFTFLOAT)
1439 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1440 M_FLD(d, REG_ATMP1, 0);
1442 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1443 M_LWZX(REG_ATMP1, d);
1445 emit_store_dst(jd, iptr, d);
1448 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1449 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1450 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1451 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1452 M_INTMOVE(s2, REG_ITMP2);
1453 M_ISSL_IMM(3, REG_ITMP2);
1454 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1455 M_ADRMOVE(s1, REG_ATMP1);
1456 M_AADDINT(REG_ITMP2, REG_ATMP1);
1457 /* implicit null-pointer check */
1458 #if !defined(ENABLE_SOFTFLOAT)
1459 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1460 M_DLD(d, REG_ATMP1, 0);
1462 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1463 M_LLD(d, REG_ATMP1, 0);
1465 emit_store_dst(jd, iptr, d);
1468 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1469 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1470 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1472 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1473 M_INTMOVE(s2, REG_ITMP2);
1474 M_ISSL_IMM(2, REG_ITMP2);
1475 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1476 M_ADRMOVE(s1, REG_ATMP1);
1477 M_AADDINT(REG_ITMP2, REG_ATMP1);
1479 /* implicit null-pointer check */
1480 M_LAX(REG_ATMP1, d);
1481 emit_store_dst(jd, iptr, d);
1485 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1486 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1487 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1488 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1489 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1490 M_INTMOVE(s2, REG_ITMP2);
1491 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1492 M_ADRMOVE(s1, REG_ATMP1);
1493 M_AADDINT(REG_ITMP2, REG_ATMP1);
1494 /* implicit null-pointer check */
1495 M_STBX(REG_ATMP1, s3);
1498 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1500 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1501 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1502 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1503 M_INTMOVE(s2, REG_ITMP2);
1504 M_ISSL_IMM(1, REG_ITMP2);
1505 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1506 M_ADRMOVE(s1, REG_ATMP1);
1507 M_AADDINT(REG_ITMP2, REG_ATMP1);
1508 /* implicit null-pointer check */
1509 M_STHX(REG_ATMP1, s3);
1512 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1514 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1515 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1516 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1517 M_INTMOVE(s2, REG_ITMP2);
1518 M_ISSL_IMM(1, REG_ITMP2);
1519 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1520 M_ADRMOVE(s1, REG_ATMP1);
1521 M_AADDINT(REG_ITMP2, REG_ATMP1);
1522 /* implicit null-pointer check */
1523 M_STHX(REG_ATMP1, s3);
1526 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1528 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1529 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1530 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1531 M_INTMOVE(s2, REG_ITMP2);
1532 M_ISSL_IMM(2, REG_ITMP2);
1533 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1534 M_ADRMOVE(s1, REG_ATMP1);
1535 M_AADDINT(REG_ITMP2, REG_ATMP1);
1536 /* implicit null-pointer check */
1537 M_STWX(REG_ATMP1, s3);
1540 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1541 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1543 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1545 M_INTMOVE(s2, REG_ITMP1);
1546 M_ISSL_IMM(3, REG_ITMP1);
1547 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1548 M_ADRMOVE(s1, REG_ATMP1);
1549 M_AADDINT(REG_ITMP1, REG_ATMP1);
1550 /* implicit null-pointer check */
1551 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1552 M_LST(s3, REG_ATMP1, 0);
1555 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1557 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1558 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1559 M_INTMOVE(s2, REG_ITMP2);
1560 M_ISSL_IMM(2, REG_ITMP2);
1561 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1562 M_ADRMOVE(s1, REG_ATMP1);
1563 M_AADDINT(REG_ITMP2, REG_ATMP1);
1564 /* implicit null-pointer check */
1565 #if !defined(ENABLE_SOFTFLOAT)
1566 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1567 M_FST(s3, REG_ATMP1, 0);
1569 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1570 M_STWX(REG_ATMP1, s3);
1574 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1577 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1578 M_INTMOVE(s2, REG_ITMP2);
1579 M_ISSL_IMM(3, REG_ITMP2);
1580 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1581 M_ADRMOVE(s1, REG_ATMP1);
1582 M_AADDINT(REG_ITMP2, REG_ATMP1);
1583 /* implicit null-pointer check */
1584 #if !defined(ENABLE_SOFTFLOAT)
1585 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1586 M_DST(s3, REG_ATMP1, 0);
1588 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1589 /* implicit null-pointer check */
1590 M_LST(s3, REG_ATMP1, 0);
1594 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1596 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1597 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1598 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1599 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1601 /* XXX what if array is NULL */
1602 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1604 M_AST(s1, REG_SP, 0*4);
1605 M_AST(s3, REG_SP, 1*4);
1606 M_JSR_IMM(BUILTIN_canstore);
1607 emit_exception_check(cd, iptr);
1609 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1610 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1611 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1612 M_INTMOVE(s2, REG_ITMP1);
1613 M_ISSL_IMM(2, REG_ITMP1);
1614 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1615 M_ADRMOVE(s1, REG_ATMP1);
1616 M_AADDINT(REG_ITMP1, REG_ATMP1);
1617 /* implicit null-pointer check */
1618 M_STAX(REG_ATMP1, s3);
1623 /* METHOD INVOCATION *********************************************************/
1624 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1625 bte = iptr->sx.s23.s3.bte;
1629 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1630 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1631 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1632 case ICMD_INVOKEINTERFACE:
1633 REPLACEMENT_POINT_INVOKE(cd, iptr);
1635 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1637 um = iptr->sx.s23.s3.um;
1638 md = um->methodref->parseddesc.md;
1641 lm = iptr->sx.s23.s3.fmiref->p.method;
1643 md = lm->parseddesc;
1646 s3 = md->paramcount;
1648 MCODECHECK((s3 << 1) + 64);
1650 /* copy arguments to stack */
1651 for (s3 = s3 - 1; s3 >= 0; s3--) {
1652 var = VAR(iptr->sx.s23.s2.args[s3]);
1653 /* already preallocated */
1654 if (var->flags & PREALLOC) continue;
1656 if (!md->params[s3].inmemory) assert(0);
1658 switch (var->type) {
1659 #if defined(ENABLE_SOFTFLOAT)
1663 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1664 M_LST(d, REG_SP, md->params[s3].regoff);
1666 #if defined(ENABLE_SOFTFLOAT)
1670 d = emit_load(jd, iptr, var, REG_ITMP1);
1671 M_IST(d, REG_SP, md->params[s3].regoff);
1674 d = emit_load(jd, iptr, var, REG_ATMP1);
1675 M_AST(d, REG_SP, md->params[s3].regoff);
1677 #if !defined(ENABLE_SOFTFLOAT)
1679 d = emit_load(jd, iptr, var, REG_FTMP1);
1680 M_FST(d, REG_SP, md->params[s3].regoff);
1683 d = emit_load(jd, iptr, var, REG_FTMP1);
1684 M_DST(d, REG_SP, md->params[s3].regoff);
1692 /* arguments in place now */
1695 disp = (ptrint) bte->fp;
1696 d = md->returntype.type;
1699 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1700 emit_exception_check(cd, iptr);
1703 case ICMD_INVOKESPECIAL:
1704 /* adress register for sure */
1705 M_ALD(REG_ATMP1, REG_SP, 0);
1706 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1708 case ICMD_INVOKESTATIC:
1710 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1712 M_AMOV_IMM(disp, REG_ATMP1);
1714 disp = lm->stubroutine;
1715 M_AMOV_IMM(disp, REG_ATMP1);
1718 /* generate the actual call */
1720 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1724 case ICMD_INVOKEVIRTUAL:
1726 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1729 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1731 /* load object pointer (==argument 0) */
1732 M_ALD(REG_ATMP1, REG_SP, 0);
1733 /* implicit null-pointer check */
1734 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1735 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1736 /* generate the actual call */
1739 case ICMD_INVOKEINTERFACE:
1741 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1746 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1747 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1749 /* load object pointer (==argument 0) */
1750 M_ALD(REG_ATMP1, REG_SP, 0);
1752 /* implicit null-pointer check */
1753 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1754 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1755 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1757 /* generate the actual call */
1759 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1763 } /* switch (iptr->opc) */
1765 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1767 /* store return value */
1768 d = md->returntype.type;
1771 case TYPE_VOID: break;
1772 #if defined(ENABLE_SOFTFLOAT)
1776 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1777 M_INTMOVE(REG_RESULT, s1);
1779 #if defined(ENABLE_SOFTFLOAT)
1783 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1784 M_LNGMOVE(REG_RESULT_PACKED, s1);
1787 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1788 /* all stuff is returned in %d0 */
1789 M_INT2ADRMOVE(REG_RESULT, s1);
1791 #if !defined(ENABLE_SOFTFLOAT)
1793 * for BUILTINS float values are returned in %d0,%d1
1794 * within cacao we use %fp0 for that.
1797 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1798 if (iptr->opc == ICMD_BUILTIN) {
1799 M_INT2FLTMOVE(REG_FRESULT, s1);
1801 M_FLTMOVE(REG_FRESULT, s1);
1805 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1806 if (iptr->opc == ICMD_BUILTIN) {
1807 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1808 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1810 M_DBLMOVE(REG_FRESULT, s1);
1817 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1818 break; /* ICMD_INVOKE* */
1820 #if defined(ENABLE_SOFTFLOAT)
1823 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1825 REPLACEMENT_POINT_RETURN(cd, iptr);
1826 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1827 M_INTMOVE(s1, REG_RESULT);
1828 goto nowperformreturn;
1830 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1832 REPLACEMENT_POINT_RETURN(cd, iptr);
1833 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1834 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1835 M_ADR2INTMOVE(s1, REG_RESULT);
1837 #ifdef ENABLE_VERIFIER
1838 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1839 unresolved_class *uc = iptr->sx.s23.s2.uc;
1841 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1843 #endif /* ENABLE_VERIFIER */
1844 goto nowperformreturn;
1846 #if defined(ENABLE_SOFTFLOAT)
1849 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1850 REPLACEMENT_POINT_RETURN(cd, iptr);
1851 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1852 M_LNGMOVE(s1, REG_RESULT_PACKED);
1853 goto nowperformreturn;
1855 #if !defined(ENABLE_SOFTFLOAT)
1856 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1857 REPLACEMENT_POINT_RETURN(cd, iptr);
1858 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1859 M_FLTMOVE(s1, REG_FRESULT);
1860 goto nowperformreturn;
1863 REPLACEMENT_POINT_RETURN(cd, iptr);
1864 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1865 M_DBLMOVE(s1, REG_FRESULT);
1866 goto nowperformreturn;
1870 case ICMD_RETURN: /* ... ==> ... */
1872 REPLACEMENT_POINT_RETURN(cd, iptr);
1878 p = cd->stackframesize;
1880 /* call trace function */
1881 #if !defined(NDEBUG)
1882 emit_verbosecall_exit(jd);
1885 #if defined(ENABLE_THREADS)
1886 /* call lock_monitor_exit */
1887 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1888 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1890 /* we need to save the proper return value */
1891 /* we do not care for the long -> doubel convert space here */
1892 switch (iptr->opc) {
1893 #if defined(ENABLE_SOFTFLOAT)
1897 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1899 #if defined(ENABLE_SOFTFLOAT)
1904 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1906 #if !defined(ENABLE_SOFTFLOAT)
1908 M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1911 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1916 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1917 M_JSR_IMM(LOCK_monitor_exit);
1919 /* and now restore the proper return value */
1920 switch (iptr->opc) {
1922 #if defined(ENABLE_SOFTFLOAT)
1926 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1928 #if defined(ENABLE_SOFTFLOAT)
1933 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1935 #if !defined(ENABLE_SOFTFLOAT)
1937 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1940 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1948 /* restore return address */
1950 if (!jd->isleafmethod) {
1951 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1952 may have a displacement overflow. */
1954 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1958 /* restore saved registers */
1960 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1961 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1963 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1964 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1966 #if !defined(ENABLE_SOFTFLOAT)
1967 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1968 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1971 /* deallocate stack */
1972 M_AADD_IMM(cd->stackframesize, REG_SP);
1978 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1979 /* val.a: (classinfo*) superclass */
1981 /* superclass is an interface:
1983 * return (sub != NULL) &&
1984 * (sub->vftbl->interfacetablelength > super->index) &&
1985 * (sub->vftbl->interfacetable[-super->index] != NULL);
1987 * superclass is a class:
1989 * return ((sub != NULL) && (0
1990 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
1991 * super->vftbl->diffvall));
1998 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2003 super = iptr->sx.s23.s3.c.cls;
2004 superindex = super->index;
2007 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2008 CODEGEN_CRITICAL_SECTION_NEW;
2010 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2013 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2014 assert(VAROP(iptr->dst)->type == TYPE_INT);
2018 /* if class is not resolved, check which code to call */
2020 if (super == NULL) {
2022 emit_label_beq(cd, BRANCH_LABEL_1);
2024 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2026 M_IMOV_IMM32(0, REG_ITMP3);
2027 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2028 emit_label_beq(cd, BRANCH_LABEL_2);
2031 /* interface instanceof code */
2033 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2034 if (super == NULL) {
2035 codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2038 emit_label_beq(cd, BRANCH_LABEL_3);
2041 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2042 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2043 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
2046 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
2052 emit_label_br(cd, BRANCH_LABEL_4);
2054 emit_label(cd, BRANCH_LABEL_3);
2057 /* class instanceof code */
2059 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2060 if (super == NULL) {
2061 emit_label(cd, BRANCH_LABEL_2);
2063 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2064 M_AMOV_IMM(0, REG_ATMP2);
2066 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2068 emit_label_beq(cd, BRANCH_LABEL_5);
2071 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2073 CODEGEN_CRITICAL_SECTION_START;
2075 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2076 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2077 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2079 CODEGEN_CRITICAL_SECTION_END;
2081 M_ISUB(REG_ITMP3, REG_ITMP1);
2082 M_ICMP(REG_ITMP2, REG_ITMP1);
2085 M_TPFW; /* overlaps next instruction */
2089 emit_label(cd, BRANCH_LABEL_5);
2092 if (super == NULL) {
2093 emit_label(cd, BRANCH_LABEL_1);
2094 emit_label(cd, BRANCH_LABEL_4);
2097 emit_store_dst(jd, iptr, d);
2101 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2102 /* val.a: (classinfo*) superclass */
2104 /* superclass is an interface:
2106 * OK if ((sub == NULL) ||
2107 * (sub->vftbl->interfacetablelength > super->index) &&
2108 * (sub->vftbl->interfacetable[-super->index] != NULL));
2110 * superclass is a class:
2112 * OK if ((sub == NULL) || (0
2113 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2114 * super->vftbl->diffvall));
2117 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2118 /* object type cast-check */
2123 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2128 super = iptr->sx.s23.s3.c.cls;
2129 superindex = super->index;
2132 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2133 CODEGEN_CRITICAL_SECTION_NEW;
2135 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2136 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2138 /* if class is not resolved, check which code to call */
2140 if (super == NULL) {
2142 emit_label_beq(cd, BRANCH_LABEL_1);
2144 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2146 M_IMOV_IMM32(0, REG_ITMP2);
2147 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2148 emit_label_beq(cd, BRANCH_LABEL_2);
2151 /* interface checkcast code */
2153 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2154 if (super == NULL) {
2155 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2158 emit_label_beq(cd, BRANCH_LABEL_3);
2161 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2162 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2164 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2166 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2168 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2170 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2173 emit_label_br(cd, BRANCH_LABEL_4);
2175 emit_label(cd, BRANCH_LABEL_3);
2178 /* class checkcast code */
2180 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2181 if (super == NULL) {
2182 emit_label(cd, BRANCH_LABEL_2);
2184 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2185 M_AMOV_IMM(0, REG_ATMP3);
2187 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2189 emit_label_beq(cd, BRANCH_LABEL_5);
2192 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2194 CODEGEN_CRITICAL_SECTION_START;
2196 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2197 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2198 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2200 CODEGEN_CRITICAL_SECTION_END;
2202 M_ISUB(REG_ITMP1, REG_ITMP3);
2203 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2205 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2208 emit_label(cd, BRANCH_LABEL_5);
2211 if (super == NULL) {
2212 emit_label(cd, BRANCH_LABEL_1);
2213 emit_label(cd, BRANCH_LABEL_4);
2216 d = codegen_reg_of_dst(jd, iptr, s1);
2218 /* array type cast-check */
2220 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2222 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2223 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2224 M_AMOV_IMM(0, REG_ATMP1);
2226 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2231 M_JSR_IMM(BUILTIN_arraycheckcast);
2232 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2234 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2236 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2237 d = codegen_reg_of_dst(jd, iptr, s1);
2239 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2241 emit_store_dst(jd, iptr, d);
2244 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2247 branch_target_t *table;
2249 table = iptr->dst.table;
2251 l = iptr->sx.s23.s2.tablelow;
2252 i = iptr->sx.s23.s3.tablehigh;
2254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2255 M_INTMOVE(s1, REG_ITMP1);
2256 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2261 M_ICMP_IMM(i - 1, REG_ITMP1);
2262 emit_bugt(cd, table[0].block);
2264 /* build jump table top down and use address of lowest entry */
2268 dseg_add_target(cd, table->block);
2272 /* length of dataseg after last dseg_add_target is used by load */
2273 M_AMOV_IMM(0, REG_ATMP2);
2276 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2277 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2278 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2279 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2286 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2289 lookup_target_t *lookup;
2291 lookup = iptr->dst.lookup;
2293 i = iptr->sx.s23.s2.lookupcount;
2295 MCODECHECK((i<<2)+8);
2296 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2299 M_ICMP_IMM(lookup->value, s1);
2300 emit_beq(cd, lookup->target.block);
2304 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2309 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2311 /* check for negative sizes and copy sizes to stack if necessary */
2312 MCODECHECK((iptr->s1.argcount << 1) + 64);
2314 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2315 var = VAR(iptr->sx.s23.s2.args[s1]);
2317 /* Already Preallocated? */
2318 if (!(var->flags & PREALLOC)) {
2319 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2320 M_IST(s2, REG_SP, (s1 + 3) * 4);
2324 /* a0 = dimension count */
2325 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2326 M_IST(REG_ITMP1, REG_SP, 0*4);
2328 /* a1 = arraydescriptor */
2329 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2330 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2331 M_AMOV_IMM(0, REG_ATMP1);
2333 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2335 M_AST(REG_ATMP1, REG_SP, 1*4);
2337 /* a2 = pointer to dimensions = stack pointer */
2338 M_AMOV(REG_SP, REG_ATMP1);
2339 M_AADD_IMM(3*4, REG_ATMP1);
2340 M_AST(REG_ATMP1, REG_SP, 2*4);
2342 M_JSR_IMM(BUILTIN_multianewarray);
2344 /* check for exception before result assignment */
2345 emit_exception_check(cd, iptr);
2347 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2348 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2349 M_INT2ADRMOVE(REG_RESULT, d);
2350 emit_store_dst(jd, iptr, d);
2356 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2357 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2360 /* M_TPF; */ /* nop after each ICMD */
2361 } /* for each instruction */
2363 /* At the end of a basic block we may have to append some nops,
2364 because the patcher stub calling code might be longer than the
2365 actual instruction. So codepatching does not change the
2366 following block unintentionally. */
2368 if (cd->mcodeptr < cd->lastmcodeptr) {
2369 while (cd->mcodeptr < cd->lastmcodeptr) {
2375 } /* if (btpre->flags >= BBREACHED) */
2376 } /* for each basic block */
2378 dseg_createlinenumbertable(cd);
2380 /* generate stubs */
2381 emit_patcher_stubs(jd);
2387 /* codegen_emit_stub_compiler **************************************************
2389 Emits a stub routine which calls the compiler.
2391 *******************************************************************************/
2393 void codegen_emit_stub_compiler(jitdata *jd)
2398 /* get required compiler data */
2403 /* code for the stub */
2405 M_AMOV_IMM(m, REG_ATMP1);
2406 M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2411 /* codegen_emit_stub_native ****************************************************
2413 Emits a stub routine which calls a native method.
2415 *******************************************************************************/
2417 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
2424 s4 nativeparams, i, j, t, s1, s2;
2426 /* get required compiler data */
2434 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2436 /* calc stackframe size */
2437 cd->stackframesize = sizeof(stackframeinfo) / SIZEOF_VOID_P +
2438 sizeof(localref_table) / SIZEOF_VOID_P +
2440 1 + /* functionptr */
2441 4; /* args for codegen_start_native_call */
2443 /* create method header */
2444 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2445 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
2446 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2447 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2448 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2449 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2450 (void) dseg_addlinenumbertablesize(cd);
2451 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2453 /* print call trace */
2454 #if !defined(NDEBUG)
2455 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2456 emit_verbosecall_enter(jd);
2461 M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2463 /* get function address (this must happen before the stackframeinfo) */
2464 #if !defined(WITH_STATIC_CLASSPATH)
2466 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2469 M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2471 M_AST(REG_ATMP2, REG_SP, 4 * 4);
2473 /* put arguments for codegen_start_native_call onto stack */
2474 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2476 M_AMOV(REG_SP, REG_ATMP1);
2477 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP1);
2479 M_ALD(REG_ATMP3, REG_ATMP1, 0 * 4);
2480 M_AST(REG_ATMP3, REG_SP, 3 * 4); /* ra */
2482 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* datasp */
2484 M_AADD_IMM(1 * 4 , REG_ATMP1);
2485 M_AST(REG_ATMP1, REG_SP, 2 * 4); /* sp */
2487 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2488 dseg_adddata(cd); /* this patches it */
2490 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2492 M_JSR_IMM(codegen_start_native_call);
2494 /* load function pointer */
2495 M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2497 /* copy arguments into stackframe */
2498 for (i = md->paramcount -1, j = i + nativeparams; i >= 0; --i, --j) {
2499 t = md->paramtypes[i].type;
2500 /* all arguments via stack */
2501 assert(md->params[i].inmemory);
2503 s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2504 s2 = nmd->params[j].regoff;
2506 /* simply copy argument stack */
2507 M_ILD(REG_ITMP1, REG_SP, s1);
2508 M_IST(REG_ITMP1, REG_SP, s2);
2509 if (IS_2_WORD_TYPE(t)) {
2510 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2511 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2515 /* for static function class as second arg */
2516 if (m->flags & ACC_STATIC) {
2517 M_AMOV_IMM(m->class, REG_ATMP1);
2518 M_AST(REG_ATMP1, REG_SP, 1 * 4);
2520 /* env ist first argument */
2521 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2522 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2524 /* call the native function */
2527 /* save return value */
2528 switch (md->returntype.type) {
2529 case TYPE_VOID: break;
2531 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2534 M_IST(REG_D1, REG_SP, 2 * 4);
2540 M_IST(REG_D0, REG_SP, 1 * 4);
2546 /* print call trace */
2547 #if ! defined(NDEBUG)
2548 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2549 emit_verbosecall_exit(jd);
2552 /* remove native stackframe info */
2553 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2555 M_AMOV(REG_SP, REG_ATMP3);
2556 M_AADD_IMM(cd->stackframesize * 4, REG_ATMP3);
2557 M_AST(REG_ATMP3, REG_SP, 0 * 4); /* datasp */
2558 M_JSR_IMM(codegen_finish_native_call);
2560 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2561 /* restore return value */
2562 switch (md->returntype.type) {
2563 case TYPE_VOID: break;
2567 M_ILD(REG_D1, REG_SP, 2 * 4);
2572 M_ILD(REG_D0, REG_SP, 1 * 4);
2577 #if !defined(ENABLE_SOFTFLOAT)
2578 /* additionally load values into floating points registers
2579 * as cacao jit code expects them there */
2580 switch (md->returntype.type) {
2582 M_FLD(REG_D0, REG_SP, 1 * 4);
2585 M_DLD(REG_D0, REG_SP, 1 * 4);
2589 /* restore saved registers */
2591 M_AADD_IMM(cd->stackframesize*4, REG_SP);
2592 /* check for exception */
2597 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2599 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2600 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2601 M_JMP_IMM(asm_handle_nat_exception);
2603 /* should never be reached from within jit code*/
2606 /* generate patcher stub call code */
2607 emit_patcher_stubs(jd);
2612 * These are local overrides for various environment variables in Emacs.
2613 * Please do not remove this and leave it at the end of the file, where
2614 * Emacs will automagically detect them.
2615 * ---------------------------------------------------------------------
2618 * indent-tabs-mode: t
2622 * vim:noexpandtab:sw=4:ts=4: