1 /* src/vm/jit/m68k/codegen.c
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
37 #include "vm/jit/m68k/codegen.h"
38 #include "vm/jit/m68k/emit.h"
40 #include "mm/memory.h"
41 #include "native/jni.h"
42 #include "native/localref.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
50 #include "vm/stringlocal.h"
53 #include "vm/jit/asmpart.h"
54 #include "vm/jit/codegen-common.h"
55 #include "vm/jit/dseg.h"
56 #include "vm/jit/emit-common.h"
57 #include "vm/jit/jit.h"
58 #include "vm/jit/abi.h"
59 #include "vm/jit/parse.h"
60 #include "vm/jit/patcher.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
63 #include "vm/jit/stacktrace.h"
64 #include "vm/jit/md.h"
66 #include "vmcore/loader.h"
67 #include "vmcore/options.h"
68 #include "vmcore/utf8.h"
71 bool codegen_emit(jitdata *jd)
77 s4 len, s1, s2, s3, d, disp;
83 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
84 unresolved_method *um;
85 builtintable_entry *bte;
92 /* get required compiler data */
99 /* prevent compiler warnings */
107 /* save calle saved registers */
108 s4 savedregs_num = 0;
110 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
111 savedregs_num += (ADR_SAV_CNT - rd->savadrreguse);
112 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
114 cd->stackframesize = rd->memuse + savedregs_num;
116 /* we always add 2 stack slots.
117 * 1 word the lock word, which may be unused and resides @ rd->memuse * 8
118 * + 2 words to either save the return value for LOCK_monitor_exit @ rd->memuse * 8 + 8
119 * on the other hand we could use 2 words when a builtin returns a doulbe which are
120 * returned in %d0, %d1 and need to be stored onto the stack and read in used a fmovemd
121 * so we always _need_ at least 2 slots, and this keeps the code simple */
122 cd->stackframesize += 2;
124 cd->stackframesize *= 8; /* we use 8 byte stack slots */
127 #if defined(ENABLE_THREADS)
128 /* we need additional space to save argument of monitor_enter */
129 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
130 if (IS_2_WORD_TYPE(m->parseddesc->returntype.type)) {
131 cd->stackframesize += 2;
133 cd->stackframesize += 1;
139 /* create method header */
140 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
141 (void) dseg_add_unique_s4(cd, cd->stackframesize); /* FrameSize */
142 #if defined(ENABLE_THREADS)
143 if (checksync && (m->flags & ACC_SYNCHRONIZED))
144 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8);/* IsSync */
147 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
149 /* REMOVEME: We still need it for exception handling in assembler. */
151 if (code_is_leafmethod(code))
152 (void) dseg_add_unique_s4(cd, 1);
154 (void) dseg_add_unique_s4(cd, 0);
156 /* XXX we use the IntSave a split field for the adr now */
157 (void) dseg_add_unique_s4(cd, (ADR_SAV_CNT - rd->savadrreguse) << 16 | (INT_SAV_CNT - rd->savintreguse)); /* IntSave */
158 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
160 dseg_addlinenumbertablesize(cd);
162 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
164 /* create exception table */
165 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
166 dseg_add_target(cd, ex->start);
167 dseg_add_target(cd, ex->end);
168 dseg_add_target(cd, ex->handler);
169 (void) dseg_add_unique_address(cd, ex->catchtype.any);
172 #if defined(ENABLE_PROFILING)
177 emit_verbosecall_enter(jd);
179 /* create stack frame */
180 M_AADD_IMM(-(cd->stackframesize), REG_SP);
182 /* save used callee saved registers */
183 p = cd->stackframesize;
184 for (i=INT_SAV_CNT-1; i>=rd->savintreguse; --i) {
185 p-=8; M_IST(rd->savintregs[i], REG_SP, p);
187 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
188 p-=8; M_AST(rd->savadrregs[i], REG_SP, p);
190 #if !defined(ENABLE_SOFTFLOAT)
191 for (i=FLT_SAV_CNT-1; i>=rd->savfltreguse; --i) {
192 p-=8; M_FSTORE(rd->savfltregs[i], REG_SP, p);
195 assert(FLT_SAV_CNT == 0);
196 assert(rd->savfltreguse == 0);
198 /* take arguments out of stack frame */
200 for (p = 0, l = 0; p < md->paramcount; p++) {
201 t = md->paramtypes[p].type;
202 varindex = jd->local_map[l * 5 + t];
205 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
208 if (varindex == UNUSED)
213 s1 = md->params[p].regoff;
214 assert(md->params[p].inmemory); /* all args are on stack */
217 #if defined(ENABLE_SOFTFLOAT)
223 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
224 if (IS_2_WORD_TYPE(t)) {
225 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
227 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
229 } else { /* stack arg -> spilled */
230 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4);
231 M_IST(REG_ITMP1, REG_SP, var->vv.regoff);
232 if (IS_2_WORD_TYPE(t)) {
233 M_ILD(REG_ITMP1, REG_SP, cd->stackframesize + s1 + 4 + 4);
234 M_IST(REG_ITMP1, REG_SP, var->vv.regoff + 4);
238 #if !defined(ENABLE_SOFTFLOAT)
241 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
242 if (IS_2_WORD_TYPE(t)) {
243 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
245 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
247 } else { /* stack-arg -> spilled */
248 if (IS_2_WORD_TYPE(t)) {
249 M_DLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
250 M_DST(REG_FTMP1, REG_SP, var->vv.regoff);
252 M_FLD(REG_FTMP1, REG_SP, cd->stackframesize + s1 + 4);
253 M_FST(REG_FTMP1, REG_SP, var->vv.regoff);
257 #endif /* SOFTFLOAT */
259 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
260 M_ALD(var->vv.regoff, REG_SP, cd->stackframesize + s1 + 4);
261 } else { /* stack-arg -> spilled */
262 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + s1 + 4);
263 M_AST(REG_ATMP1, REG_SP, var->vv.regoff);
268 } /* end for argument out of stack*/
270 #if defined(ENABLE_THREADS)
271 /* call lock_monitor_enter function */
272 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
273 if (m->flags & ACC_STATIC) {
274 M_AMOV_IMM((&m->class->object.header), REG_ATMP1);
276 /* for non-static case the first arg is the object */
277 M_ALD(REG_ATMP1, REG_SP, cd->stackframesize + 4);
280 M_TRAP(M68K_EXCEPTION_HARDWARE_NULLPOINTER);
283 M_AST(REG_ATMP1, REG_SP, rd->memuse * 8);
284 M_AST(REG_ATMP1, REG_SP, 0 * 4);
285 M_JSR_IMM(LOCK_monitor_enter);
291 /* create replacement points */
292 REPLACEMENT_POINTS_INIT(cd, jd);
294 /* foreach basic block */
295 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
297 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
299 if (bptr->flags >= BBREACHED) {
301 /* branch resolving */
302 codegen_resolve_branchrefs(cd, bptr);
304 /* handle replacement points */
305 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
307 #if defined(ENABLE_PROFILING)
310 /* FIXME there are still some constrcuts to copy in here */
312 #if defined(ENABLE_LSRA)
316 /* copy interface registers to their destination */
322 var = VAR(bptr->invars[len]);
323 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
324 d = codegen_reg_of_var(0, var, REG_ATMP1_XPTR);
325 M_ADRMOVE(REG_ATMP1_XPTR, d);
326 emit_store(jd, NULL, var, d);
329 assert((var->flags & INOUT));
333 /* walk through all instructions */
337 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
338 if (iptr->line != currentline) {
339 dseg_addlinenumber(cd, iptr->line);
340 currentline = iptr->line;
343 MCODECHECK(1024); /* 1kB should be enough */
346 case ICMD_NOP: /* ... ==> ... */
347 case ICMD_POP: /* ..., value ==> ... */
348 case ICMD_POP2: /* ..., value, value ==> ... */
351 case ICMD_INLINE_START:
353 REPLACEMENT_POINT_INLINE_START(cd, iptr);
356 case ICMD_INLINE_BODY:
358 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
359 dseg_addlinenumber_inline_start(cd, iptr);
360 dseg_addlinenumber(cd, iptr->line);
363 case ICMD_INLINE_END:
365 dseg_addlinenumber_inline_end(cd, iptr);
366 dseg_addlinenumber(cd, iptr->line);
369 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
371 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
372 assert(VAROP(iptr->s1)->type == TYPE_ADR);
373 emit_nullpointer_check(cd, iptr, s1);
377 /* CONST **************************************************************/
378 case ICMD_ICONST: /* ... ==> ..., constant */
379 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
380 M_IMOV_IMM(iptr->sx.val.i, d);
381 emit_store_dst(jd, iptr, d);
384 case ICMD_LCONST: /* ... ==> ..., constant */
386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
387 LCONST(iptr->sx.val.l, d);
388 emit_store_dst(jd, iptr, d);
391 case ICMD_FCONST: /* ... ==> ..., constant */
393 #if defined(ENABLE_SOFTFLOAT)
394 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
395 M_IMOV_IMM(iptr->sx.val.i, d);
396 emit_store_dst(jd, iptr, d);
398 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
399 FCONST(iptr->sx.val.i, d);
400 emit_store_dst(jd, iptr, d);
404 case ICMD_DCONST: /* ... ==> ..., constant */
406 #if defined(ENABLE_SOFTFLOAT)
407 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
408 LCONST(iptr->sx.val.l, d);
409 emit_store_dst(jd, iptr, d);
411 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
412 disp = dseg_add_double(cd, iptr->sx.val.d);
413 M_AMOV_IMM(0, REG_ATMP1);
415 M_DLD(d, REG_ATMP1, disp);
416 emit_store_dst(jd, iptr, d);
421 /* some long operations *********************************************/
422 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
423 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
424 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
426 M_INTMOVE(s2, REG_ITMP1);
427 M_IADD(s1, REG_ITMP1); /* low word */
428 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
429 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
430 M_INTMOVE(s2, REG_ITMP2);
431 M_IADDX(s1, REG_ITMP2); /* high word */
432 emit_store_dst(jd, iptr, d);
435 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
436 /* sx.val.l = constant */
437 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
438 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
439 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
441 M_IMOV_IMM(iptr->sx.val.l >> 32, REG_ITMP3);
443 s3 = iptr->sx.val.l & 0xffffffff;
444 M_INTMOVE(s1, REG_ITMP1);
445 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
447 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
448 M_LNGMOVE(REG_ITMP12_PACKED, d);
449 emit_store_dst(jd, iptr, d);
452 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
453 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
454 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
456 M_INTMOVE(s1, REG_ITMP1);
457 M_ISUB(s2, REG_ITMP1); /* low word */
458 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
459 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
460 M_INTMOVE(s1, REG_ITMP2);
461 M_ISUBX(s2, REG_ITMP2); /* high word */
462 emit_store_dst(jd, iptr, d);
465 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
466 /* sx.val.l = constant */
467 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
468 s2 = emit_load_s1_high(jd, iptr, REG_ITMP2);
469 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
471 M_IMOV_IMM( (-iptr->sx.val.l) >> 32, REG_ITMP3);
473 s3 = (-iptr->sx.val.l) & 0xffffffff;
474 M_INTMOVE(s1, REG_ITMP1);
475 M_IADD_IMM(s3, REG_ITMP1); /* lower word in REG_ITMP1 now */
477 M_IADDX(REG_ITMP3, REG_ITMP2); /* high word in REG_ITMP2 now */
478 M_LNGMOVE(REG_ITMP12_PACKED, d);
479 emit_store_dst(jd, iptr, d);
482 case ICMD_LNEG: /* ..., value ==> ..., - value */
483 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
484 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
485 M_LNGMOVE(s1, REG_ITMP12_PACKED);
486 M_INEG(GET_LOW_REG(REG_ITMP12_PACKED));
487 M_INEGX(GET_HIGH_REG(REG_ITMP12_PACKED));
488 M_LNGMOVE(REG_ITMP12_PACKED, d);
489 emit_store_dst(jd, iptr, d);
492 /* integer operations ************************************************/
493 case ICMD_INEG: /* ..., value ==> ..., - value */
495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
496 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
497 M_INTMOVE(s1, REG_ITMP1);
499 M_INTMOVE(REG_ITMP1, d);
500 emit_store_dst(jd, iptr, d);
503 case ICMD_I2L: /* ..., value ==> ..., value */
505 s1 = emit_load_s1(jd, iptr, REG_ITMP3);
506 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
507 M_IMOV(s1, GET_LOW_REG(d)); /* sets negativ bit */
509 M_ISET(GET_HIGH_REG(d));
511 M_ICLR(GET_HIGH_REG(d));
513 emit_store_dst(jd, iptr, d);
516 case ICMD_L2I: /* ..., value ==> ..., value */
518 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
521 emit_store_dst(jd, iptr, d);
523 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
528 emit_store_dst(jd, iptr, d);
531 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
533 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
536 emit_store_dst(jd, iptr, d);
539 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
544 emit_store_dst(jd, iptr, d);
549 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
552 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
554 M_INTMOVE(s2, REG_ITMP2);
555 M_IADD(s1, REG_ITMP2);
556 M_INTMOVE(REG_ITMP2, d);
557 emit_store_dst(jd, iptr, d);
560 /* s1.localindex = variable, sx.val.i = constant*/
565 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
566 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
567 M_INTMOVE(s1, REG_ITMP1);
568 M_IADD_IMM(iptr->sx.val.i, REG_ITMP1);
569 M_INTMOVE(REG_ITMP1, d);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
578 M_INTMOVE(s1, REG_ITMP1);
579 M_ISUB(s2, REG_ITMP1);
580 M_INTMOVE(REG_ITMP1, d);
581 emit_store_dst(jd, iptr, d);
584 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
585 /* sx.val.i = constant */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
589 M_INTMOVE(s1, REG_ITMP1);
590 M_IADD_IMM(-iptr->sx.val.i, REG_ITMP1);
591 M_INTMOVE(REG_ITMP1, d);
592 emit_store_dst(jd, iptr, d);
595 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
599 emit_arithmetic_check(cd, iptr, s2);
600 M_INTMOVE(s1, REG_ITMP1);
601 M_IDIV(s2, REG_ITMP1);
602 M_INTMOVE(REG_ITMP1, d);
603 emit_store_dst(jd, iptr, d);
606 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
608 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
609 M_INTMOVE(s1, REG_ITMP1);
613 M_IADD_IMM((1 << iptr->sx.val.i) - 1, REG_ITMP1);
615 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
616 M_ISSR(REG_ITMP2, REG_ITMP1);
617 M_INTMOVE(REG_ITMP1, d);
618 emit_store_dst(jd, iptr, d);
621 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
624 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
625 emit_arithmetic_check(cd, iptr, s2);
627 M_ICMP_IMM(0x80000000, s1);
632 M_TPFL; /* hides the next instruction */
633 M_IREM(s2, s1, REG_ITMP3);
635 M_INTMOVE(REG_ITMP3, d);
637 emit_store_dst(jd, iptr, d);
640 case ICMD_IREMPOW2: /* ..., value ==> ..., value << constant */
641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644 M_IMOV(s1, REG_ITMP1);
648 M_IAND_IMM(iptr->sx.val.i, d);
650 M_BGE(2 + 2 + 6 + 2);
651 M_IMOV(s1, d); /* don't use M_INTMOVE, so we know the jump offset */
653 M_IAND_IMM(iptr->sx.val.i, d); /* use 32-bit for jump offset */
656 emit_store_dst(jd, iptr, d);
660 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
661 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
663 bte = iptr->sx.s23.s3.bte;
666 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
667 M_INTMOVE(GET_LOW_REG(s2), REG_ITMP3);
668 M_IOR(GET_HIGH_REG(s2), REG_ITMP3);
669 /* XXX could be optimized */
670 emit_arithmetic_check(cd, iptr, REG_ITMP3);
672 M_LST(s2, REG_SP, 2 * 4);
673 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
674 M_LST(s1, REG_SP, 0 * 4);
678 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
679 M_LNGMOVE(REG_RESULT_PACKED, d);
680 emit_store_dst(jd, iptr, d);
683 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
688 M_INTMOVE(s2, REG_ITMP2);
689 M_IMUL(s1, REG_ITMP2);
690 M_INTMOVE(REG_ITMP2, d);
691 emit_store_dst(jd, iptr, d);
694 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
695 /* sx.val.i = constant */
696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
698 M_IMOV_IMM(iptr->sx.val.i, REG_ITMP2);
699 M_IMUL(s1, REG_ITMP2);
700 M_INTMOVE(REG_ITMP2, d);
701 emit_store_dst(jd, iptr, d);
704 case ICMD_ISHL: /* ..., 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_ITMP1);
709 M_INTMOVE(s1, REG_ITMP1);
710 M_INTMOVE(s2, REG_ITMP2);
711 M_IAND_IMM(0x1f, REG_ITMP2);
712 M_ISSL(REG_ITMP2, REG_ITMP1);
713 M_INTMOVE(REG_ITMP1, d);
714 emit_store_dst(jd, iptr, d);
717 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
718 /* sx.val.i = constant */
720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
722 if (iptr->sx.val.i & 0x1f) {
723 M_INTMOVE(s1, REG_ITMP1)
724 if ((iptr->sx.val.i & 0x1f) <= 7) {
725 M_ISSL_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
727 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
728 M_ISSL(REG_ITMP2, REG_ITMP1);
730 M_INTMOVE(REG_ITMP1, d);
734 emit_store_dst(jd, iptr, d);
737 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
739 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
740 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
741 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
742 M_INTMOVE(s1, REG_ITMP1);
743 M_INTMOVE(s2, REG_ITMP2);
744 M_IAND_IMM(0x1f, REG_ITMP2);
745 M_ISSR(REG_ITMP2, REG_ITMP1);
746 M_INTMOVE(REG_ITMP1, d);
747 emit_store_dst(jd, iptr, d);
750 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
751 /* sx.val.i = constant */
753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
755 if (iptr->sx.val.i & 0x1f) {
756 M_INTMOVE(s1, REG_ITMP1)
757 if ((iptr->sx.val.i & 0x1f) <= 7) {
758 M_ISSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
760 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
761 M_ISSR(REG_ITMP2, REG_ITMP1);
763 M_INTMOVE(REG_ITMP1, d);
767 emit_store_dst(jd, iptr, d);
770 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
774 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
775 M_INTMOVE(s1, REG_ITMP1);
776 M_INTMOVE(s2, REG_ITMP2);
777 M_IAND_IMM(0x1f, REG_ITMP2);
778 M_IUSR(REG_ITMP2, REG_ITMP1);
779 M_INTMOVE(REG_ITMP1, d);
780 emit_store_dst(jd, iptr, d);
783 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
784 /* sx.val.i = constant */
785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
786 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
787 if (iptr->sx.val.i & 0x1f) {
788 M_INTMOVE(s1, REG_ITMP1)
789 if ((iptr->sx.val.i & 0x1f) <= 7) {
790 M_IUSR_IMM(iptr->sx.val.i & 0x1f, REG_ITMP1);
792 M_IMOV_IMM(iptr->sx.val.i & 0x1f, REG_ITMP2);
793 M_IUSR(REG_ITMP2, REG_ITMP1);
795 M_INTMOVE(REG_ITMP1, d);
799 emit_store_dst(jd, iptr, d);
802 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
805 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
807 M_INTMOVE(s2, REG_ITMP2);
808 M_IAND(s1, REG_ITMP2);
809 M_INTMOVE(REG_ITMP2, d);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
814 /* sx.val.i = constant */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
818 M_INTMOVE(s1, REG_ITMP1);
819 M_IAND_IMM(iptr->sx.val.i, REG_ITMP1);
820 M_INTMOVE(REG_ITMP1, d);
821 emit_store_dst(jd, iptr, d);
824 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
827 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828 M_INTMOVE(s2, REG_ITMP2);
829 M_IOR(s1, REG_ITMP2);
830 M_INTMOVE(REG_ITMP2, d);
831 emit_store_dst(jd, iptr, d);
834 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
835 /* sx.val.i = constant */
836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
837 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
838 M_INTMOVE(s1, REG_ITMP1);
839 M_IOR_IMM(iptr->sx.val.i, REG_ITMP1);
840 M_INTMOVE(REG_ITMP1, d);
841 emit_store_dst(jd, iptr, d);
844 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 | val2 */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
848 M_INTMOVE(s2, REG_ITMP2);
849 M_IXOR(s1, REG_ITMP2);
850 M_INTMOVE(REG_ITMP2, d);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_IXORCONST: /* ..., value ==> ..., value | constant */
855 /* sx.val.i = constant */
856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
858 M_INTMOVE(s1, REG_ITMP1);
859 M_IXOR_IMM(iptr->sx.val.i, REG_ITMP1);
860 M_INTMOVE(REG_ITMP1, d);
861 emit_store_dst(jd, iptr, d);
864 /* floating point operations ******************************************/
865 #if !defined(ENABLE_SOFTFLOAT)
866 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
868 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
869 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
870 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
873 M_BFUN(14); /* result is -1, branch to end */
874 M_BFLT(10); /* result is -1, branch to end */
876 M_BFEQ(4) /* result is 0, branch to end */
878 emit_store_dst(jd, iptr, d);
881 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
883 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
884 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
888 M_BFUN(16); /* result is +1, branch to end */
889 M_BFGT(14); /* result is +1, branch to end */
891 M_BFEQ(8) /* result is 0, branch to end */
893 emit_store_dst(jd, iptr, d);
896 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
897 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
898 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
899 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
900 M_FLTMOVE(s2, REG_FTMP2);
901 M_FMUL(s1, REG_FTMP2);
902 M_FLTMOVE(REG_FTMP2, d);
903 emit_store_dst(jd, iptr, d);
906 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
907 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
908 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
909 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
910 M_DBLMOVE(s2, REG_FTMP2);
911 M_DMUL(s1, REG_FTMP2);
912 M_DBLMOVE(REG_FTMP2, d);
913 emit_store_dst(jd, iptr, d);
916 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
917 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
918 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
919 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
920 M_FLTMOVE(s1, REG_FTMP1);
921 M_FDIV(s2, REG_FTMP1);
922 M_FLTMOVE(REG_FTMP1, d);
923 emit_store_dst(jd, iptr, d);
926 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
927 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
928 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
929 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
930 M_DBLMOVE(s1, REG_FTMP1);
931 M_DDIV(s2, REG_FTMP1);
932 M_DBLMOVE(REG_FTMP1, d);
933 emit_store_dst(jd, iptr, d);
936 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
937 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
938 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
939 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
940 M_FLTMOVE(s2, REG_FTMP2);
941 M_FADD(s1, REG_FTMP2);
942 M_FLTMOVE(REG_FTMP2, d);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
947 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
948 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
949 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
950 M_DBLMOVE(s2, REG_FTMP2);
951 M_DADD(s1, REG_FTMP2);
952 M_DBLMOVE(REG_FTMP2, d);
953 emit_store_dst(jd, iptr, d);
956 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
957 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
958 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
959 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
960 M_FLTMOVE(s1, REG_FTMP1);
961 M_FSUB(s2, REG_FTMP1);
962 M_FLTMOVE(REG_FTMP1, d);
963 emit_store_dst(jd, iptr, d);
966 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
967 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
968 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
969 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
970 M_DBLMOVE(s1, REG_FTMP1);
971 M_DSUB(s2, REG_FTMP1);
972 M_DBLMOVE(REG_FTMP1, d);
973 emit_store_dst(jd, iptr, d);
976 case ICMD_F2D: /* ..., value ==> ..., (double) value */
977 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
978 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
980 emit_store_dst(jd, iptr, d);
983 case ICMD_D2F: /* ..., value ==> ..., (float) value */
984 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
985 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
987 emit_store_dst(jd, iptr, d);
990 case ICMD_FNEG: /* ..., value ==> ..., - value */
991 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
992 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
994 emit_store_dst(jd, iptr, d);
997 case ICMD_DNEG: /* ..., value ==> ..., - value */
998 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
999 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1001 emit_store_dst(jd, iptr, d);
1006 /* load/store/copy/move operations ************************************/
1008 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
1009 case ICMD_ALOAD: /* s1 = local variable */
1013 case ICMD_ISTORE: /* ..., value ==> ... */
1020 emit_copy(jd, iptr);
1025 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
1026 emit_copy(jd, iptr);
1030 case ICMD_ACONST: /* ... ==> ..., constant */
1031 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1033 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1034 constant_classref *cr = iptr->sx.val.c.ref;;
1035 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, cr, 0);
1038 M_AMOV_IMM(iptr->sx.val.anyptr, d);
1040 emit_store_dst(jd, iptr, d);
1042 /* BRANCH *************************************************************/
1044 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1046 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1047 M_ADRMOVE(s1, REG_ATMP1_XPTR);
1049 #ifdef ENABLE_VERIFIER
1050 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1051 unresolved_class *uc = iptr->sx.s23.s2.uc;
1053 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1055 #endif /* ENABLE_VERIFIER */
1056 M_JSR_PCREL(2); /* get current PC */
1059 M_AMOV_IMM(asm_handle_exception, REG_ATMP3);
1064 case ICMD_GOTO: /* ... ==> ... */
1065 case ICMD_RET: /* ... ==> ... */
1067 emit_br(cd, iptr->dst.block);
1071 case ICMD_JSR: /* ... ==> ... */
1073 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
1079 case ICMD_IFNULL: /* ..., value ==> ... */
1080 case ICMD_IFNONNULL:
1081 assert(IS_ADR_TYPE(VAROP(iptr->s1)->type));
1082 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1084 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, BRANCH_OPT_NONE);
1092 case ICMD_IFEQ: /* ..., value ==> ... */
1094 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1095 assert (VAROP(iptr->s1)->type == TYPE_INT);
1096 M_ICMP_IMM(iptr->sx.val.i, s1);
1097 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IFEQ, BRANCH_OPT_NONE);
1100 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1101 case ICMD_IF_ICMPNE:
1102 case ICMD_IF_ICMPLT:
1103 case ICMD_IF_ICMPGT:
1104 case ICMD_IF_ICMPLE:
1105 case ICMD_IF_ICMPGE:
1107 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1108 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1110 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ICMPEQ, BRANCH_OPT_NONE);
1113 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
1114 case ICMD_IF_ACMPNE:
1116 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1117 s2 = emit_load_s2(jd, iptr, REG_ATMP2);
1119 emit_bcc(cd, iptr->dst.block, iptr->opc - ICMD_IF_ACMPEQ, BRANCH_OPT_NONE);
1123 /* MEMORY *************************************************************/
1125 case ICMD_GETSTATIC: /* ... ==> ..., value */
1127 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1128 uf = iptr->sx.s23.s3.uf;
1129 fieldtype = uf->fieldref->parseddesc.fd->type;
1132 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1135 fi = iptr->sx.s23.s3.fmiref->p.field;
1136 fieldtype = fi->type;
1137 disp = (intptr_t) fi->value;
1139 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1140 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1145 M_AMOV_IMM(disp, REG_ATMP1);
1146 switch (fieldtype) {
1147 #if defined(ENABLE_SOFTFLOAT)
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1152 M_ILD(d, REG_ATMP1, 0);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1156 M_ALD(d, REG_ATMP1, 0);
1158 #if defined(ENABLE_SOFTFLOAT)
1162 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1163 M_LLD(d, REG_ATMP1, 0);
1165 #if !defined(ENABLE_SOFTFLOAT)
1167 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1168 M_FLD(d, REG_ATMP1, 0);
1171 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1172 M_DLD(d, REG_ATMP1, 0);
1176 emit_store_dst(jd, iptr, d);
1179 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1181 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1182 uf = iptr->sx.s23.s3.uf;
1183 fieldtype = uf->fieldref->parseddesc.fd->type;
1186 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, 0);
1189 fi = iptr->sx.s23.s3.fmiref->p.field;
1190 fieldtype = fi->type;
1191 disp = (intptr_t) fi->value;
1193 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1194 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1198 M_AMOV_IMM(disp, REG_ATMP1);
1199 switch (fieldtype) {
1200 #if defined(ENABLE_SOFTFLOAT)
1204 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1205 M_IST(s1, REG_ATMP1, 0);
1207 #if defined(ENABLE_SOFTFLOAT)
1211 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
1212 M_LST(s1, REG_ATMP1, 0);
1215 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1216 M_AST(s1, REG_ATMP1, 0);
1218 #if !defined(ENABLE_SOFTFLOAT)
1220 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1221 M_FST(s1, REG_ATMP1, 0);
1224 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1225 M_DST(s1, REG_ATMP1, 0);
1232 case ICMD_GETFIELD: /* ... ==> ..., value */
1234 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1236 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1237 uf = iptr->sx.s23.s3.uf;
1238 fieldtype = uf->fieldref->parseddesc.fd->type;
1241 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1244 fi = iptr->sx.s23.s3.fmiref->p.field;
1245 fieldtype = fi->type;
1249 /* implicit null-pointer check */
1250 switch (fieldtype) {
1251 #if defined(ENABLE_SOFTFLOAT)
1255 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1258 #if defined(ENABLE_SOFTFLOAT)
1262 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1269 #if !defined(ENABLE_SOFTFLOAT)
1271 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1275 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1280 emit_store_dst(jd, iptr, d);
1283 case ICMD_PUTFIELD: /* ..., value ==> ... */
1285 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1287 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1288 uf = iptr->sx.s23.s3.uf;
1289 fieldtype = uf->fieldref->parseddesc.fd->type;
1293 fi = iptr->sx.s23.s3.fmiref->p.field;
1294 fieldtype = fi->type;
1298 if (IS_INT_LNG_TYPE(fieldtype)) {
1299 if (IS_2_WORD_TYPE(fieldtype)) {
1300 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
1302 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1305 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1308 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1309 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
1311 /* implicit null-pointer check */
1312 switch (fieldtype) {
1313 #if defined(ENABLE_SOFTFLOAT)
1317 M_IST(s2, s1, disp);
1320 #if defined(ENABLE_SOFTFLOAT)
1324 M_LST(s2, s1, disp);
1327 M_AST(s2, s1, disp);
1329 #if !defined(ENABLE_SOFTFLOAT)
1331 M_FST(s2, s1, disp);
1334 M_DST(s2, s1, disp);
1340 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1342 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1343 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1344 /* implicit null-pointer check */
1345 M_ILD(d, s1, OFFSET(java_array_t, size));
1346 emit_store_dst(jd, iptr, d);
1349 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1351 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1354 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1355 M_INTMOVE(s2, REG_ITMP2);
1356 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1357 M_ADRMOVE(s1, REG_ATMP1);
1358 M_AADDINT(REG_ITMP2, REG_ATMP1);
1359 /* implicit null-pointer check */
1360 M_LBZX(REG_ATMP1, d);
1362 emit_store_dst(jd, iptr, d);
1365 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1367 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1368 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1370 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1371 M_INTMOVE(s2, REG_ITMP2);
1372 M_ISSL_IMM(1, REG_ITMP2);
1373 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1374 M_ADRMOVE(s1, REG_ATMP1);
1375 M_AADDINT(REG_ITMP2, REG_ATMP1);
1376 /* implicit null-pointer check */
1377 M_LHZX(REG_ATMP1, d);
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1384 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1385 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1386 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1387 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1388 M_INTMOVE(s2, REG_ITMP2);
1389 M_ISSL_IMM(1, REG_ITMP2);
1390 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1391 M_ADRMOVE(s1, REG_ATMP1);
1392 M_AADDINT(REG_ITMP2, REG_ATMP1);
1394 /* implicit null-pointer check */
1395 M_LHZX(REG_ATMP1, d);
1397 emit_store_dst(jd, iptr, d);
1400 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1402 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1403 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1404 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1405 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1406 M_INTMOVE(s2, REG_ITMP2);
1407 M_ISSL_IMM(2, REG_ITMP2);
1408 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1409 M_ADRMOVE(s1, REG_ATMP1);
1410 M_AADDINT(REG_ITMP2, REG_ATMP1);
1411 /* implicit null-pointer check */
1412 M_LWZX(REG_ATMP1, d);
1413 emit_store_dst(jd, iptr, d);
1416 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1417 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1418 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1420 /* implicit null-pointer check */
1421 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1422 M_INTMOVE(s2, REG_ITMP1);
1423 M_ISSL_IMM(3, REG_ITMP1);
1424 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1425 M_ADRMOVE(s1, REG_ATMP1);
1426 M_AADDINT(REG_ITMP1, REG_ATMP1);
1427 /* implicit null-pointer check */
1428 M_LLD(d, REG_ATMP1, 0);
1429 emit_store_dst(jd, iptr, d);
1432 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1433 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1434 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1435 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1436 M_INTMOVE(s2, REG_ITMP2);
1437 M_ISSL_IMM(2, REG_ITMP2);
1438 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1439 M_ADRMOVE(s1, REG_ATMP1);
1440 M_AADDINT(REG_ITMP2, REG_ATMP1);
1441 /* implicit null-pointer check */
1442 #if !defined(ENABLE_SOFTFLOAT)
1443 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1444 M_FLD(d, REG_ATMP1, 0);
1446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1447 M_LWZX(REG_ATMP1, d);
1449 emit_store_dst(jd, iptr, d);
1452 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1453 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1454 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1455 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1456 M_INTMOVE(s2, REG_ITMP2);
1457 M_ISSL_IMM(3, REG_ITMP2);
1458 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1459 M_ADRMOVE(s1, REG_ATMP1);
1460 M_AADDINT(REG_ITMP2, REG_ATMP1);
1461 /* implicit null-pointer check */
1462 #if !defined(ENABLE_SOFTFLOAT)
1463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1464 M_DLD(d, REG_ATMP1, 0);
1466 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1467 M_LLD(d, REG_ATMP1, 0);
1469 emit_store_dst(jd, iptr, d);
1472 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1473 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1474 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1475 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1476 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1477 M_INTMOVE(s2, REG_ITMP2);
1478 M_ISSL_IMM(2, REG_ITMP2);
1479 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP2);
1480 M_ADRMOVE(s1, REG_ATMP1);
1481 M_AADDINT(REG_ITMP2, REG_ATMP1);
1483 /* implicit null-pointer check */
1484 M_LAX(REG_ATMP1, d);
1485 emit_store_dst(jd, iptr, d);
1489 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1490 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1491 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1492 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1493 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1494 M_INTMOVE(s2, REG_ITMP2);
1495 M_IADD_IMM(OFFSET(java_bytearray_t, data[0]), REG_ITMP2);
1496 M_ADRMOVE(s1, REG_ATMP1);
1497 M_AADDINT(REG_ITMP2, REG_ATMP1);
1498 /* implicit null-pointer check */
1499 M_STBX(REG_ATMP1, s3);
1502 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1504 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1505 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1506 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1507 M_INTMOVE(s2, REG_ITMP2);
1508 M_ISSL_IMM(1, REG_ITMP2);
1509 M_IADD_IMM(OFFSET(java_chararray_t, data[0]), REG_ITMP2);
1510 M_ADRMOVE(s1, REG_ATMP1);
1511 M_AADDINT(REG_ITMP2, REG_ATMP1);
1512 /* implicit null-pointer check */
1513 M_STHX(REG_ATMP1, s3);
1516 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1520 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1521 M_INTMOVE(s2, REG_ITMP2);
1522 M_ISSL_IMM(1, REG_ITMP2);
1523 M_IADD_IMM(OFFSET(java_shortarray_t, data[0]), REG_ITMP2);
1524 M_ADRMOVE(s1, REG_ATMP1);
1525 M_AADDINT(REG_ITMP2, REG_ATMP1);
1526 /* implicit null-pointer check */
1527 M_STHX(REG_ATMP1, s3);
1530 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1533 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1534 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1535 M_INTMOVE(s2, REG_ITMP2);
1536 M_ISSL_IMM(2, REG_ITMP2);
1537 M_IADD_IMM(OFFSET(java_intarray_t, data[0]), REG_ITMP2);
1538 M_ADRMOVE(s1, REG_ATMP1);
1539 M_AADDINT(REG_ITMP2, REG_ATMP1);
1540 /* implicit null-pointer check */
1541 M_STWX(REG_ATMP1, s3);
1544 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1545 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1546 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1547 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1549 M_INTMOVE(s2, REG_ITMP1);
1550 M_ISSL_IMM(3, REG_ITMP1);
1551 M_IADD_IMM(OFFSET(java_longarray_t, data[0]), REG_ITMP1);
1552 M_ADRMOVE(s1, REG_ATMP1);
1553 M_AADDINT(REG_ITMP1, REG_ATMP1);
1554 /* implicit null-pointer check */
1555 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1556 M_LST(s3, REG_ATMP1, 0);
1559 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1561 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1562 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1563 M_INTMOVE(s2, REG_ITMP2);
1564 M_ISSL_IMM(2, REG_ITMP2);
1565 M_IADD_IMM(OFFSET(java_floatarray_t, data[0]), REG_ITMP2);
1566 M_ADRMOVE(s1, REG_ATMP1);
1567 M_AADDINT(REG_ITMP2, REG_ATMP1);
1568 /* implicit null-pointer check */
1569 #if !defined(ENABLE_SOFTFLOAT)
1570 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1571 M_FST(s3, REG_ATMP1, 0);
1573 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1574 M_STWX(REG_ATMP1, s3);
1578 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1580 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1581 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1582 M_INTMOVE(s2, REG_ITMP2);
1583 M_ISSL_IMM(3, REG_ITMP2);
1584 M_IADD_IMM(OFFSET(java_doublearray_t, data[0]), REG_ITMP2);
1585 M_ADRMOVE(s1, REG_ATMP1);
1586 M_AADDINT(REG_ITMP2, REG_ATMP1);
1587 /* implicit null-pointer check */
1588 #if !defined(ENABLE_SOFTFLOAT)
1589 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1590 M_DST(s3, REG_ATMP1, 0);
1592 s3 = emit_load_s3(jd, iptr, REG_ITMP12_PACKED);
1593 /* implicit null-pointer check */
1594 M_LST(s3, REG_ATMP1, 0);
1598 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1600 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1601 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1602 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1603 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1605 /* XXX what if array is NULL */
1606 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1608 M_AST(s1, REG_SP, 0*4);
1609 M_AST(s3, REG_SP, 1*4);
1610 M_JSR_IMM(BUILTIN_FAST_canstore);
1611 emit_arraystore_check(cd, iptr);
1613 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
1614 s2 = emit_load_s2(jd, iptr, REG_ITMP1);
1615 s3 = emit_load_s3(jd, iptr, REG_ATMP2);
1616 M_INTMOVE(s2, REG_ITMP1);
1617 M_ISSL_IMM(2, REG_ITMP1);
1618 M_IADD_IMM(OFFSET(java_objectarray_t, data[0]), REG_ITMP1);
1619 M_ADRMOVE(s1, REG_ATMP1);
1620 M_AADDINT(REG_ITMP1, REG_ATMP1);
1621 /* implicit null-pointer check */
1622 M_STAX(REG_ATMP1, s3);
1627 /* METHOD INVOCATION *********************************************************/
1628 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
1629 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
1631 bte = iptr->sx.s23.s3.bte;
1635 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1636 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1637 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1638 case ICMD_INVOKEINTERFACE:
1639 REPLACEMENT_POINT_INVOKE(cd, iptr);
1641 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1643 um = iptr->sx.s23.s3.um;
1644 md = um->methodref->parseddesc.md;
1647 lm = iptr->sx.s23.s3.fmiref->p.method;
1649 md = lm->parseddesc;
1652 s3 = md->paramcount;
1654 MCODECHECK((s3 << 1) + 64);
1656 /* copy arguments to stack */
1657 for (s3 = s3 - 1; s3 >= 0; s3--) {
1658 var = VAR(iptr->sx.s23.s2.args[s3]);
1659 /* already preallocated */
1660 if (var->flags & PREALLOC) continue;
1662 if (!md->params[s3].inmemory) assert(0);
1664 switch (var->type) {
1665 #if defined(ENABLE_SOFTFLOAT)
1669 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
1670 M_LST(d, REG_SP, md->params[s3].regoff);
1672 #if defined(ENABLE_SOFTFLOAT)
1676 d = emit_load(jd, iptr, var, REG_ITMP1);
1677 M_IST(d, REG_SP, md->params[s3].regoff);
1680 d = emit_load(jd, iptr, var, REG_ATMP1);
1681 M_AST(d, REG_SP, md->params[s3].regoff);
1683 #if !defined(ENABLE_SOFTFLOAT)
1685 d = emit_load(jd, iptr, var, REG_FTMP1);
1686 M_FST(d, REG_SP, md->params[s3].regoff);
1689 d = emit_load(jd, iptr, var, REG_FTMP1);
1690 M_DST(d, REG_SP, md->params[s3].regoff);
1698 /* arguments in place now */
1701 if (bte->stub == NULL)
1702 disp = (ptrint) bte->fp;
1704 disp = (ptrint) bte->stub;
1705 d = md->returntype.type;
1708 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1711 case ICMD_INVOKESPECIAL:
1712 /* adress register for sure */
1713 M_ALD(REG_ATMP1, REG_SP, 0);
1714 emit_nullpointer_check(cd, iptr, REG_ATMP1);
1716 case ICMD_INVOKESTATIC:
1718 codegen_addpatchref(cd, PATCHER_invokestatic_special, um, 0);
1720 M_AMOV_IMM(disp, REG_ATMP1);
1722 disp = lm->stubroutine;
1723 M_AMOV_IMM(disp, REG_ATMP1);
1726 /* generate the actual call */
1728 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1732 case ICMD_INVOKEVIRTUAL:
1734 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
1737 s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
1739 /* load object pointer (==argument 0) */
1740 M_ALD(REG_ATMP1, REG_SP, 0);
1741 /* implicit null-pointer check */
1742 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1743 M_ALD(REG_ATMP3, REG_METHODPTR, s1);
1744 /* generate the actual call */
1747 case ICMD_INVOKEINTERFACE:
1749 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
1754 s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->class->index;
1755 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1757 /* load object pointer (==argument 0) */
1758 M_ALD(REG_ATMP1, REG_SP, 0);
1760 /* implicit null-pointer check */
1761 M_ALD(REG_METHODPTR, REG_ATMP1, OFFSET(java_object_t, vftbl));
1762 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
1763 M_ALD(REG_ATMP3, REG_METHODPTR, s2);
1765 /* generate the actual call */
1767 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1771 } /* switch (iptr->opc) */
1773 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
1774 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
1776 /* store return value */
1777 d = md->returntype.type;
1780 case TYPE_VOID: break;
1781 #if defined(ENABLE_SOFTFLOAT)
1785 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
1786 M_INTMOVE(REG_RESULT, s1);
1788 #if defined(ENABLE_SOFTFLOAT)
1792 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1793 M_LNGMOVE(REG_RESULT_PACKED, s1);
1796 s1 = codegen_reg_of_dst(jd, iptr, REG_ATMP1);
1797 /* all stuff is returned in %d0 */
1798 M_INT2ADRMOVE(REG_RESULT, s1);
1800 #if !defined(ENABLE_SOFTFLOAT)
1802 * for BUILTINS float values are returned in %d0,%d1
1803 * within cacao we use %fp0 for that.
1806 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1807 if (iptr->opc == ICMD_BUILTIN) {
1808 M_INT2FLTMOVE(REG_FRESULT, s1);
1810 M_FLTMOVE(REG_FRESULT, s1);
1814 s1 = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1815 if (iptr->opc == ICMD_BUILTIN) {
1816 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 4 + 4);
1817 M_DLD(s1, REG_SP, rd->memuse * 4 + 4);
1819 M_DBLMOVE(REG_FRESULT, s1);
1826 if (d != TYPE_VOID) emit_store_dst(jd, iptr, s1);
1827 break; /* ICMD_INVOKE* */
1829 #if defined(ENABLE_SOFTFLOAT)
1832 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1834 REPLACEMENT_POINT_RETURN(cd, iptr);
1835 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1836 M_INTMOVE(s1, REG_RESULT);
1837 goto nowperformreturn;
1839 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1841 REPLACEMENT_POINT_RETURN(cd, iptr);
1842 s1 = emit_load_s1(jd, iptr, REG_RESULT);
1843 assert(VAROP(iptr->s1)->type == TYPE_ADR);
1844 M_ADR2INTMOVE(s1, REG_RESULT);
1846 #ifdef ENABLE_VERIFIER
1847 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1848 unresolved_class *uc = iptr->sx.s23.s2.uc;
1850 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
1852 #endif /* ENABLE_VERIFIER */
1853 goto nowperformreturn;
1855 #if defined(ENABLE_SOFTFLOAT)
1858 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1859 REPLACEMENT_POINT_RETURN(cd, iptr);
1860 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
1861 M_LNGMOVE(s1, REG_RESULT_PACKED);
1862 goto nowperformreturn;
1864 #if !defined(ENABLE_SOFTFLOAT)
1865 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1866 REPLACEMENT_POINT_RETURN(cd, iptr);
1867 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1868 M_FLTMOVE(s1, REG_FRESULT);
1869 goto nowperformreturn;
1872 REPLACEMENT_POINT_RETURN(cd, iptr);
1873 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
1874 M_DBLMOVE(s1, REG_FRESULT);
1875 goto nowperformreturn;
1879 case ICMD_RETURN: /* ... ==> ... */
1881 REPLACEMENT_POINT_RETURN(cd, iptr);
1887 p = cd->stackframesize;
1889 /* call trace function */
1890 #if !defined(NDEBUG)
1891 emit_verbosecall_exit(jd);
1894 #if defined(ENABLE_THREADS)
1895 /* call lock_monitor_exit */
1896 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1897 M_ILD(REG_ITMP3, REG_SP, rd->memuse * 8);
1899 /* we need to save the proper return value */
1900 /* we do not care for the long -> doubel convert space here */
1901 switch (iptr->opc) {
1902 #if defined(ENABLE_SOFTFLOAT)
1906 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1908 #if defined(ENABLE_SOFTFLOAT)
1913 M_IST(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1915 #if !defined(ENABLE_SOFTFLOAT)
1917 M_FST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1920 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1925 M_IST(REG_ITMP3, REG_SP, 0 * 4);
1926 M_JSR_IMM(LOCK_monitor_exit);
1928 /* and now restore the proper return value */
1929 switch (iptr->opc) {
1931 #if defined(ENABLE_SOFTFLOAT)
1935 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8 + 8);
1937 #if defined(ENABLE_SOFTFLOAT)
1942 M_ILD(REG_RESULT , REG_SP, rd->memuse * 8 + 8);
1944 #if !defined(ENABLE_SOFTFLOAT)
1946 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1949 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8 + 8);
1957 /* restore return address */
1959 if (!code_is_leafmethod(code)) {
1960 /* ATTENTION: Don't use REG_ZERO (r0) here, as M_ALD
1961 may have a displacement overflow. */
1963 M_ALD(REG_ITMP1, REG_SP, p * 4 + LA_LR_OFFSET);
1967 /* restore saved registers */
1969 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
1970 p-=8; M_ILD(rd->savintregs[i], REG_SP, p);
1972 for (i=ADR_SAV_CNT-1; i>=rd->savadrreguse; --i) {
1973 p-=8; M_ALD(rd->savadrregs[i], REG_SP, p);
1975 #if !defined(ENABLE_SOFTFLOAT)
1976 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
1977 p-=8; M_FLOAD(rd->savfltregs[i], REG_SP, p);
1980 /* deallocate stack */
1981 M_AADD_IMM(cd->stackframesize, REG_SP);
1987 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1988 /* val.a: (classinfo*) superclass */
1990 /* superclass is an interface:
1992 * return (sub != NULL) &&
1993 * (sub->vftbl->interfacetablelength > super->index) &&
1994 * (sub->vftbl->interfacetable[-super->index] != NULL);
1996 * superclass is a class:
1998 * return ((sub != NULL) && (0
1999 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2000 * super->vftbl->diffvall));
2007 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2012 super = iptr->sx.s23.s3.c.cls;
2013 superindex = super->index;
2016 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2017 CODEGEN_CRITICAL_SECTION_NEW;
2019 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2020 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2022 assert(VAROP(iptr->s1 )->type == TYPE_ADR);
2023 assert(VAROP(iptr->dst)->type == TYPE_INT);
2027 /* if class is not resolved, check which code to call */
2029 if (super == NULL) {
2031 emit_label_beq(cd, BRANCH_LABEL_1);
2033 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2035 M_IMOV_IMM32(0, REG_ITMP3);
2036 M_IAND_IMM(ACC_INTERFACE, REG_ITMP3);
2037 emit_label_beq(cd, BRANCH_LABEL_2);
2040 /* interface instanceof code */
2042 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2043 if (super == NULL) {
2044 codegen_addpatchref(cd, PATCHER_instanceof_interface, iptr->sx.s23.s3.c.ref, 0);
2047 emit_label_beq(cd, BRANCH_LABEL_3);
2050 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2051 M_ILD(REG_ITMP3, REG_ATMP1, OFFSET(vftbl_t, interfacetablelength));
2052 M_IADD_IMM(-superindex, REG_ITMP3); /* -superindex may be patched patched */
2055 M_ALD(REG_ATMP1, REG_ATMP1, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patch here too! */
2061 emit_label_br(cd, BRANCH_LABEL_4);
2063 emit_label(cd, BRANCH_LABEL_3);
2066 /* class instanceof code */
2068 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2069 if (super == NULL) {
2070 emit_label(cd, BRANCH_LABEL_2);
2072 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2073 M_AMOV_IMM(0, REG_ATMP2);
2075 M_AMOV_IMM(super->vftbl, REG_ATMP2);
2077 emit_label_beq(cd, BRANCH_LABEL_5);
2080 M_ALD(REG_ATMP1, s1, OFFSET(java_object_t, vftbl));
2082 CODEGEN_CRITICAL_SECTION_START;
2084 M_ILD(REG_ITMP1, REG_ATMP1, OFFSET(vftbl_t, baseval));
2085 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval));
2086 M_ILD(REG_ITMP2, REG_ATMP2, OFFSET(vftbl_t, diffval));
2088 CODEGEN_CRITICAL_SECTION_END;
2090 M_ISUB(REG_ITMP3, REG_ITMP1);
2091 M_ICMP(REG_ITMP2, REG_ITMP1);
2094 M_TPFW; /* overlaps next instruction */
2098 emit_label(cd, BRANCH_LABEL_5);
2101 if (super == NULL) {
2102 emit_label(cd, BRANCH_LABEL_1);
2103 emit_label(cd, BRANCH_LABEL_4);
2106 emit_store_dst(jd, iptr, d);
2110 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2111 /* val.a: (classinfo*) superclass */
2113 /* superclass is an interface:
2115 * OK if ((sub == NULL) ||
2116 * (sub->vftbl->interfacetablelength > super->index) &&
2117 * (sub->vftbl->interfacetable[-super->index] != NULL));
2119 * superclass is a class:
2121 * OK if ((sub == NULL) || (0
2122 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2123 * super->vftbl->diffvall));
2126 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2127 /* object type cast-check */
2132 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2137 super = iptr->sx.s23.s3.c.cls;
2138 superindex = super->index;
2141 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2142 CODEGEN_CRITICAL_SECTION_NEW;
2144 s1 = emit_load_s1(jd, iptr, REG_ATMP1);
2145 assert(VAROP(iptr->s1)->type == TYPE_ADR);
2147 /* if class is not resolved, check which code to call */
2149 if (super == NULL) {
2151 emit_label_beq(cd, BRANCH_LABEL_1);
2153 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags, iptr->sx.s23.s3.c.ref, 0);
2155 M_IMOV_IMM32(0, REG_ITMP2);
2156 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
2157 emit_label_beq(cd, BRANCH_LABEL_2);
2160 /* interface checkcast code */
2162 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2163 if (super == NULL) {
2164 codegen_addpatchref(cd, PATCHER_checkcast_interface, iptr->sx.s23.s3.c.ref, 0);
2167 emit_label_beq(cd, BRANCH_LABEL_3);
2170 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2171 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetablelength));
2173 M_IADD_IMM(-superindex, REG_ITMP3); /* superindex patched */
2175 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2177 M_ALD(REG_ATMP3, REG_ATMP2, OFFSET(vftbl_t, interfacetable[0]) - superindex * sizeof(methodptr*)); /* patched*/
2179 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ATMP3, s1);
2182 emit_label_br(cd, BRANCH_LABEL_4);
2184 emit_label(cd, BRANCH_LABEL_3);
2187 /* class checkcast code */
2189 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2190 if (super == NULL) {
2191 emit_label(cd, BRANCH_LABEL_2);
2193 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl, iptr->sx.s23.s3.c.ref, 0);
2194 M_AMOV_IMM(0, REG_ATMP3);
2196 M_AMOV_IMM(super->vftbl, REG_ATMP3);
2198 emit_label_beq(cd, BRANCH_LABEL_5);
2201 M_ALD(REG_ATMP2, s1, OFFSET(java_object_t, vftbl));
2203 CODEGEN_CRITICAL_SECTION_START;
2205 M_ILD(REG_ITMP3, REG_ATMP2, OFFSET(vftbl_t, baseval)); /* REG_ITMP3 == sub->vftbl->baseval */
2206 M_ILD(REG_ITMP1, REG_ATMP3, OFFSET(vftbl_t, baseval));
2207 M_ILD(REG_ITMP2, REG_ATMP3, OFFSET(vftbl_t, diffval));
2209 CODEGEN_CRITICAL_SECTION_END;
2211 M_ISUB(REG_ITMP1, REG_ITMP3);
2212 M_ICMP(REG_ITMP2, REG_ITMP3); /* XXX was CMPU */
2214 emit_classcast_check(cd, iptr, BRANCH_UGT, REG_ITMP3, s1); /* XXX was BRANCH_GT */
2217 emit_label(cd, BRANCH_LABEL_5);
2220 if (super == NULL) {
2221 emit_label(cd, BRANCH_LABEL_1);
2222 emit_label(cd, BRANCH_LABEL_4);
2225 d = codegen_reg_of_dst(jd, iptr, s1);
2227 /* array type cast-check */
2229 s1 = emit_load_s1(jd, iptr, REG_ATMP2);
2231 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2232 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2233 M_AMOV_IMM(0, REG_ATMP1);
2235 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2240 M_JSR_IMM(BUILTIN_arraycheckcast);
2241 M_AADD_IMM(2*4, REG_SP); /* pop arguments off stack */
2243 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2245 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2246 d = codegen_reg_of_dst(jd, iptr, s1);
2248 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2250 emit_store_dst(jd, iptr, d);
2253 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2256 branch_target_t *table;
2258 table = iptr->dst.table;
2260 l = iptr->sx.s23.s2.tablelow;
2261 i = iptr->sx.s23.s3.tablehigh;
2263 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2264 M_INTMOVE(s1, REG_ITMP1);
2265 if (l != 0) M_ISUB_IMM(l, REG_ITMP1);
2270 M_ICMP_IMM(i - 1, REG_ITMP1);
2271 emit_bugt(cd, table[0].block);
2273 /* build jump table top down and use address of lowest entry */
2277 dseg_add_target(cd, table->block);
2281 /* length of dataseg after last dseg_add_target is used by load */
2282 M_AMOV_IMM(0, REG_ATMP2);
2285 M_ISSL_IMM(2, REG_ITMP1); /* index * 4 == offset in table */
2286 M_AADDINT(REG_ITMP1, REG_ATMP2); /* offset in table */
2287 M_AADD_IMM(-(cd->dseglen), REG_ATMP2); /* start of table in dseg */
2288 M_ALD(REG_ATMP1, REG_ATMP2, 0);
2295 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2298 lookup_target_t *lookup;
2300 lookup = iptr->dst.lookup;
2302 i = iptr->sx.s23.s2.lookupcount;
2304 MCODECHECK((i<<2)+8);
2305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2308 M_ICMP_IMM(lookup->value, s1);
2309 emit_beq(cd, lookup->target.block);
2313 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2318 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2320 /* check for negative sizes and copy sizes to stack if necessary */
2321 MCODECHECK((iptr->s1.argcount << 1) + 64);
2323 for (s1 = iptr->s1.argcount; --s1 >= 0;) {
2324 var = VAR(iptr->sx.s23.s2.args[s1]);
2326 /* Already Preallocated? */
2327 if (!(var->flags & PREALLOC)) {
2328 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2329 M_IST(s2, REG_SP, (s1 + 3) * 4);
2333 /* a0 = dimension count */
2334 M_IMOV_IMM(iptr->s1.argcount, REG_ITMP1);
2335 M_IST(REG_ITMP1, REG_SP, 0*4);
2337 /* a1 = arraydescriptor */
2338 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2339 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo, iptr->sx.s23.s3.c.ref, 0);
2340 M_AMOV_IMM(0, REG_ATMP1);
2342 M_AMOV_IMM(iptr->sx.s23.s3.c.cls, REG_ATMP1);
2344 M_AST(REG_ATMP1, REG_SP, 1*4);
2346 /* a2 = pointer to dimensions = stack pointer */
2347 M_AMOV(REG_SP, REG_ATMP1);
2348 M_AADD_IMM(3*4, REG_ATMP1);
2349 M_AST(REG_ATMP1, REG_SP, 2*4);
2351 M_JSR_IMM(BUILTIN_multianewarray);
2353 /* check for exception before result assignment */
2354 emit_exception_check(cd, iptr);
2356 assert(VAROP(iptr->dst)->type == TYPE_ADR);
2357 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2358 M_INT2ADRMOVE(REG_RESULT, d);
2359 emit_store_dst(jd, iptr, d);
2365 printf("UNKNOWN OPCODE %d\n", iptr->opc);
2366 exceptions_throw_internalerror("Unknown ICMD %d during code generation", iptr->opc);
2369 /* M_TPF; */ /* nop after each ICMD */
2370 } /* for each instruction */
2372 /* At the end of a basic block we may have to append some nops,
2373 because the patcher stub calling code might be longer than the
2374 actual instruction. So codepatching does not change the
2375 following block unintentionally. */
2377 if (cd->mcodeptr < cd->lastmcodeptr) {
2378 while (cd->mcodeptr < cd->lastmcodeptr) {
2384 } /* if (btpre->flags >= BBREACHED) */
2385 } /* for each basic block */
2387 dseg_createlinenumbertable(cd);
2389 /* generate stubs */
2390 emit_patcher_stubs(jd);
2396 /* codegen_emit_stub_compiler **************************************************
2398 Emits a stub routine which calls the compiler.
2400 *******************************************************************************/
2402 void codegen_emit_stub_compiler(jitdata *jd)
2407 /* get required compiler data */
2412 /* code for the stub */
2414 M_AMOV_IMM(m, REG_ATMP1);
2415 M_AMOV_IMM(asm_call_jit_compiler, REG_ATMP3);
2418 /* codegen_emit_stub_native ****************************************************
2420 Emits a stub routine which calls a native method.
2422 *******************************************************************************/
2424 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
2433 /* get required compiler data */
2442 /* calc stackframe size */
2443 cd->stackframesize =
2444 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
2445 sizeof(localref_table) / SIZEOF_VOID_P +
2447 1 + /* functionptr */
2448 4; /* args for codegen_start_native_call */
2450 /* create method header */
2451 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2452 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
2453 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2454 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2455 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2456 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2457 (void) dseg_addlinenumbertablesize(cd);
2458 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2460 /* print call trace */
2461 #if !defined(NDEBUG)
2462 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2463 emit_verbosecall_enter(jd);
2468 M_AADD_IMM(-(cd->stackframesize*4), REG_SP);
2470 /* get function address (this must happen before the stackframeinfo) */
2472 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, 0);
2475 M_AMOV_IMM(f, REG_ATMP2); /* do not move this line, the patcher is needed */
2477 M_AST(REG_ATMP2, REG_SP, 4 * 4);
2479 /* put arguments for codegen_start_native_call onto stack */
2480 /* void codegen_start_native_call(u1 *datasp, u1 *pv, u1 *sp, u1 *ra) */
2482 M_AMOV(REG_SP, REG_ATMP1);
2483 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2485 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2486 dseg_adddata(cd); /* this patches it */
2488 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2490 M_JSR_IMM(codegen_start_native_call);
2492 /* remember class argument */
2493 if (m->flags & ACC_STATIC)
2494 M_INT2ADRMOVE(REG_RESULT, REG_ATMP3);
2496 /* load function pointer */
2497 M_ALD(REG_ATMP2, REG_SP, 4 * 4);
2499 /* copy arguments into stackframe */
2500 for (i = md->paramcount -1, j = i + skipparams; i >= 0; --i, --j) {
2501 t = md->paramtypes[i].type;
2502 /* all arguments via stack */
2503 assert(md->params[i].inmemory);
2505 s1 = md->params[i].regoff + cd->stackframesize * 4 + 4;
2506 s2 = nmd->params[j].regoff;
2508 /* simply copy argument stack */
2509 M_ILD(REG_ITMP1, REG_SP, s1);
2510 M_IST(REG_ITMP1, REG_SP, s2);
2511 if (IS_2_WORD_TYPE(t)) {
2512 M_ILD(REG_ITMP1, REG_SP, s1 + 4);
2513 M_IST(REG_ITMP1, REG_SP, s2 + 4);
2517 /* for static function class as second arg */
2518 if (m->flags & ACC_STATIC)
2519 M_AST(REG_ATMP3, REG_SP, 1 * 4);
2521 /* env ist first argument */
2522 M_AMOV_IMM(_Jv_env, REG_ATMP1);
2523 M_AST(REG_ATMP1, REG_SP, 0 * 4);
2525 /* call the native function */
2528 /* save return value */
2529 switch (md->returntype.type) {
2530 case TYPE_VOID: break;
2532 /* natives return float arguments in %d0, %d1, cacao expects them in %fp0 */
2535 M_IST(REG_D1, REG_SP, 2 * 4);
2541 M_IST(REG_D0, REG_SP, 2 * 4);
2547 /* print call trace */
2548 #if ! defined(NDEBUG)
2549 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
2550 emit_verbosecall_exit(jd);
2553 /* remove native stackframe info */
2554 /* therefore we call: java_objectheader *codegen_finish_native_call(u1 *datasp) */
2556 M_AMOV(REG_SP, REG_ATMP1);
2557 M_AST(REG_ATMP1, REG_SP, 0 * 4); /* currentsp */
2559 M_AMOV_IMM(0, REG_ATMP2); /* 0 needs to patched */
2560 dseg_adddata(cd); /* this patches it */
2562 M_AST(REG_ATMP2, REG_SP, 1 * 4); /* pv */
2564 M_JSR_IMM(codegen_finish_native_call);
2566 M_INT2ADRMOVE(REG_RESULT, REG_ATMP1);
2567 /* restore return value */
2568 switch (md->returntype.type) {
2569 case TYPE_VOID: break;
2573 M_ILD(REG_D1, REG_SP, 2 * 4);
2578 M_ILD(REG_D0, REG_SP, 2 * 4);
2583 #if !defined(ENABLE_SOFTFLOAT)
2584 /* additionally load values into floating points registers
2585 * as cacao jit code expects them there */
2586 switch (md->returntype.type) {
2588 M_FLD(REG_D0, REG_SP, 2 * 4);
2591 M_DLD(REG_D0, REG_SP, 2 * 4);
2595 /* restore saved registers */
2597 M_AADD_IMM(cd->stackframesize*4, REG_SP);
2598 /* check for exception */
2603 /* handle exception, REG_ATMP1 already contains exception object, REG_ATMP2 holds address */
2605 M_ALD(REG_ATMP2_XPC, REG_SP, 0); /* take return address as faulting instruction */
2606 M_AADD_IMM(-2, REG_ATMP2_XPC); /* which is off by 2 */
2607 M_JMP_IMM(asm_handle_nat_exception);
2609 /* should never be reached from within jit code*/
2612 /* generate patcher stub call code */
2613 emit_patcher_stubs(jd);
2618 * These are local overrides for various environment variables in Emacs.
2619 * Please do not remove this and leave it at the end of the file, where
2620 * Emacs will automagically detect them.
2621 * ---------------------------------------------------------------------
2624 * indent-tabs-mode: t
2628 * vim:noexpandtab:sw=4:ts=4: