1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
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 8318 2007-08-16 10:05:34Z michi $
40 #include "vm/jit/alpha/arch.h"
41 #include "vm/jit/alpha/codegen.h"
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/localref.h"
47 #include "native/native.h"
49 #include "threads/lock-common.h"
51 #include "vm/builtin.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
56 #include "vm/jit/abi.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit-common.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher-common.h"
64 #include "vm/jit/reg.h"
65 #include "vm/jit/replace.h"
66 #include "vm/jit/stacktrace.h"
68 #if defined(ENABLE_LSRA)
69 # include "vm/jit/allocator/lsra.h"
72 #include "vmcore/loader.h"
73 #include "vmcore/options.h"
76 /* codegen_emit ****************************************************************
78 Generates machine code.
80 *******************************************************************************/
82 bool codegen_emit(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
94 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
95 unresolved_method *um;
96 builtintable_entry *bte;
103 /* get required compiler data */
110 /* prevent compiler warnings */
123 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
125 /* space to save used callee saved registers */
127 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
128 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
130 cd->stackframesize = rd->memuse + savedregs_num;
132 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
133 if (checksync && (m->flags & ACC_SYNCHRONIZED))
134 cd->stackframesize++;
137 /* create method header */
140 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
143 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
144 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
146 #if defined(ENABLE_THREADS)
147 /* IsSync contains the offset relative to the stack pointer for the
148 argument of monitor_exit used in the exception handler. Since the
149 offset could be zero and give a wrong meaning of the flag it is
153 if (checksync && (m->flags & ACC_SYNCHRONIZED))
154 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
157 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
159 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
160 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
161 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
163 dseg_addlinenumbertablesize(cd);
165 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
167 /* create exception table */
169 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
170 dseg_add_target(cd, ex->start);
171 dseg_add_target(cd, ex->end);
172 dseg_add_target(cd, ex->handler);
173 (void) dseg_add_unique_address(cd, ex->catchtype.any);
176 /* create stack frame (if necessary) */
178 if (cd->stackframesize)
179 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
181 /* save return address and used callee saved registers */
183 p = cd->stackframesize;
184 if (!jd->isleafmethod) {
185 p--; M_AST(REG_RA, REG_SP, p * 8);
187 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
188 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
190 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
191 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
194 /* take arguments out of register or stack frame */
198 for (p = 0, l = 0; p < md->paramcount; p++) {
199 t = md->paramtypes[p].type;
201 varindex = jd->local_map[l * 5 + t];
204 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
207 if (varindex == UNUSED)
212 s1 = md->params[p].regoff;
214 if (IS_INT_LNG_TYPE(t)) { /* integer args */
215 if (!md->params[p].inmemory) { /* register arguments */
216 if (!IS_INMEMORY(var->flags))
217 M_INTMOVE(s1, var->vv.regoff);
219 M_LST(s1, REG_SP, var->vv.regoff);
221 else { /* stack arguments */
222 if (!IS_INMEMORY(var->flags))
223 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
225 var->vv.regoff = cd->stackframesize * 8 + s1;
228 else { /* floating args */
229 if (!md->params[p].inmemory) { /* register arguments */
230 if (!IS_INMEMORY(var->flags))
231 M_FLTMOVE(s1, var->vv.regoff);
233 M_DST(s1, REG_SP, var->vv.regoff * 8);
235 else { /* stack arguments */
236 if (!(var->flags & INMEMORY))
237 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
239 var->vv.regoff = cd->stackframesize * 8 + s1;
244 /* call monitorenter function */
246 #if defined(ENABLE_THREADS)
247 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
248 /* stack offset for monitor argument */
253 if (opt_verbosecall) {
254 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
256 for (p = 0; p < INT_ARG_CNT; p++)
257 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
259 for (p = 0; p < FLT_ARG_CNT; p++)
260 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
262 s1 += INT_ARG_CNT + FLT_ARG_CNT;
264 #endif /* !defined(NDEBUG) */
266 /* decide which monitor enter function to call */
268 if (m->flags & ACC_STATIC) {
269 disp = dseg_add_address(cd, &m->class->object.header);
270 M_ALD(REG_A0, REG_PV, disp);
274 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
277 M_AST(REG_A0, REG_SP, s1 * 8);
278 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
279 M_ALD(REG_PV, REG_PV, disp);
280 M_JSR(REG_RA, REG_PV);
281 disp = (s4) (cd->mcodeptr - cd->mcodebase);
282 M_LDA(REG_PV, REG_RA, -disp);
285 if (opt_verbosecall) {
286 for (p = 0; p < INT_ARG_CNT; p++)
287 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
289 for (p = 0; p < FLT_ARG_CNT; p++)
290 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
292 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
294 #endif /* !defined(NDEBUG) */
298 /* call trace function */
301 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
302 emit_verbosecall_enter(jd);
307 /* end of header generation */
309 /* create replacement points */
311 REPLACEMENT_POINTS_INIT(cd, jd);
313 /* walk through all basic blocks */
315 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
317 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
319 if (bptr->flags >= BBREACHED) {
321 /* branch resolving */
323 codegen_resolve_branchrefs(cd, bptr);
325 /* handle replacement points */
327 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
329 /* copy interface registers to their destination */
333 #if defined(ENABLE_LSRA)
337 src = bptr->invars[len];
338 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
339 /* d = reg_of_var(m, src, REG_ITMP1); */
340 if (!(src->flags & INMEMORY))
344 M_INTMOVE(REG_ITMP1, d);
345 emit_store(jd, NULL, src, d);
352 var = VAR(bptr->invars[len]);
353 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
354 d = codegen_reg_of_var(0, var, REG_ITMP1);
355 M_INTMOVE(REG_ITMP1, d);
356 emit_store(jd, NULL, var, d);
359 assert((var->flags & INOUT));
362 #if defined(ENABLE_LSRA)
366 /* walk through all instructions */
370 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
371 if (iptr->line != currentline) {
372 dseg_addlinenumber(cd, iptr->line);
373 currentline = iptr->line;
376 MCODECHECK(64); /* an instruction usually needs < 64 words */
379 case ICMD_NOP: /* ... ==> ... */
380 case ICMD_POP: /* ..., value ==> ... */
381 case ICMD_POP2: /* ..., value, value ==> ... */
384 case ICMD_INLINE_START:
386 REPLACEMENT_POINT_INLINE_START(cd, iptr);
389 case ICMD_INLINE_BODY:
391 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
392 dseg_addlinenumber_inline_start(cd, iptr);
393 dseg_addlinenumber(cd, iptr->line);
396 case ICMD_INLINE_END:
398 dseg_addlinenumber_inline_end(cd, iptr);
399 dseg_addlinenumber(cd, iptr->line);
402 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
405 emit_nullpointer_check(cd, iptr, s1);
408 /* constant operations ************************************************/
410 case ICMD_ICONST: /* ... ==> ..., constant */
412 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
413 ICONST(d, iptr->sx.val.i);
414 emit_store_dst(jd, iptr, d);
417 case ICMD_LCONST: /* ... ==> ..., constant */
419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
420 LCONST(d, iptr->sx.val.l);
421 emit_store_dst(jd, iptr, d);
424 case ICMD_FCONST: /* ... ==> ..., constant */
426 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
427 disp = dseg_add_float(cd, iptr->sx.val.f);
428 M_FLD(d, REG_PV, disp);
429 emit_store_dst(jd, iptr, d);
432 case ICMD_DCONST: /* ... ==> ..., constant */
434 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
435 disp = dseg_add_double(cd, iptr->sx.val.d);
436 M_DLD(d, REG_PV, disp);
437 emit_store_dst(jd, iptr, d);
440 case ICMD_ACONST: /* ... ==> ..., constant */
442 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
444 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
445 constant_classref *cr = iptr->sx.val.c.ref;
447 disp = dseg_add_unique_address(cd, cr);
449 /* XXX Only add the patcher, if this position needs to
450 be patched. If there was a previous position which
451 resolved the same class, the returned displacement
452 of dseg_add_address is ok to use. */
454 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
457 M_ALD(d, REG_PV, disp);
460 if (iptr->sx.val.anyptr == NULL)
461 M_INTMOVE(REG_ZERO, d);
463 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
464 M_ALD(d, REG_PV, disp);
467 emit_store_dst(jd, iptr, d);
471 /* load/store/move/copy operations ************************************/
473 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
474 case ICMD_ALOAD: /* s1 = local variable */
478 case ICMD_ISTORE: /* ..., value ==> ... */
490 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
495 /* integer operations *************************************************/
497 case ICMD_INEG: /* ..., value ==> ..., - value */
499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
501 M_ISUB(REG_ZERO, s1, d);
502 emit_store_dst(jd, iptr, d);
505 case ICMD_LNEG: /* ..., value ==> ..., - value */
507 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
509 M_LSUB(REG_ZERO, s1, d);
510 emit_store_dst(jd, iptr, d);
513 case ICMD_I2L: /* ..., value ==> ..., value */
515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
516 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
518 emit_store_dst(jd, iptr, d);
521 case ICMD_L2I: /* ..., value ==> ..., value */
523 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
524 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
525 M_IADD(s1, REG_ZERO, d);
526 emit_store_dst(jd, iptr, d);
529 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
533 if (has_ext_instr_set) {
536 M_SLL_IMM(s1, 56, d);
537 M_SRA_IMM( d, 56, d);
539 emit_store_dst(jd, iptr, d);
542 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
547 emit_store_dst(jd, iptr, d);
550 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
554 if (has_ext_instr_set) {
557 M_SLL_IMM(s1, 48, d);
558 M_SRA_IMM( d, 48, d);
560 emit_store_dst(jd, iptr, d);
564 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
567 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
570 emit_store_dst(jd, iptr, d);
574 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
575 /* sx.val.i = constant */
577 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
579 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
580 M_IADD_IMM(s1, iptr->sx.val.i, d);
581 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
582 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
584 /* XXX maybe use M_LDA? */
585 ICONST(REG_ITMP2, iptr->sx.val.i);
586 M_IADD(s1, REG_ITMP2, d);
588 emit_store_dst(jd, iptr, d);
591 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
597 emit_store_dst(jd, iptr, d);
600 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
601 /* sx.val.l = constant */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
605 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
606 M_LADD_IMM(s1, iptr->sx.val.l, d);
608 LCONST(REG_ITMP2, iptr->sx.val.l);
609 M_LADD(s1, REG_ITMP2, d);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
617 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 emit_store_dst(jd, iptr, d);
623 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
624 /* sx.val.i = constant */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
628 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
629 M_ISUB_IMM(s1, iptr->sx.val.i, d);
631 ICONST(REG_ITMP2, iptr->sx.val.i);
632 M_ISUB(s1, REG_ITMP2, d);
634 emit_store_dst(jd, iptr, d);
637 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
643 emit_store_dst(jd, iptr, d);
646 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
647 /* sx.val.l = constant */
649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
650 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
651 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
652 M_LSUB_IMM(s1, iptr->sx.val.l, d);
654 LCONST(REG_ITMP2, iptr->sx.val.l);
655 M_LSUB(s1, REG_ITMP2, d);
657 emit_store_dst(jd, iptr, d);
660 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
663 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
666 emit_store_dst(jd, iptr, d);
669 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
670 /* sx.val.i = constant */
672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
674 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
675 M_IMUL_IMM(s1, iptr->sx.val.i, d);
677 ICONST(REG_ITMP2, iptr->sx.val.i);
678 M_IMUL(s1, REG_ITMP2, d);
680 emit_store_dst(jd, iptr, d);
683 case ICMD_LMUL: /* ..., 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);
689 emit_store_dst(jd, iptr, d);
692 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
693 /* sx.val.l = constant */
695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
696 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
697 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
698 M_LMUL_IMM(s1, iptr->sx.val.l, d);
700 LCONST(REG_ITMP2, iptr->sx.val.l);
701 M_LMUL(s1, REG_ITMP2, d);
703 emit_store_dst(jd, iptr, d);
706 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
707 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
709 s1 = emit_load_s1(jd, iptr, REG_A0);
710 s2 = emit_load_s2(jd, iptr, REG_A1);
711 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
712 emit_arithmetic_check(cd, iptr, s2);
714 M_INTMOVE(s1, REG_A0);
715 M_INTMOVE(s2, REG_A1);
716 bte = iptr->sx.s23.s3.bte;
717 disp = dseg_add_functionptr(cd, bte->fp);
718 M_ALD(REG_PV, REG_PV, disp);
719 M_JSR(REG_RA, REG_PV);
720 disp = (s4) (cd->mcodeptr - cd->mcodebase);
721 M_LDA(REG_PV, REG_RA, -disp);
723 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
724 emit_store_dst(jd, iptr, d);
727 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
728 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
730 s1 = emit_load_s1(jd, iptr, REG_A0);
731 s2 = emit_load_s2(jd, iptr, REG_A1);
732 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
733 emit_arithmetic_check(cd, iptr, s2);
735 M_INTMOVE(s1, REG_A0);
736 M_INTMOVE(s2, REG_A1);
737 bte = iptr->sx.s23.s3.bte;
738 disp = dseg_add_functionptr(cd, bte->fp);
739 M_ALD(REG_PV, REG_PV, disp);
740 M_JSR(REG_RA, REG_PV);
741 disp = (s4) (cd->mcodeptr - cd->mcodebase);
742 M_LDA(REG_PV, REG_RA, -disp);
744 M_INTMOVE(REG_RESULT, d);
745 emit_store_dst(jd, iptr, d);
748 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
749 case ICMD_LDIVPOW2: /* val.i = constant */
751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
752 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
753 if (iptr->sx.val.i <= 15) {
754 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
755 M_CMOVGE(s1, s1, REG_ITMP2);
757 M_SRA_IMM(s1, 63, REG_ITMP2);
758 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
759 M_LADD(s1, REG_ITMP2, REG_ITMP2);
761 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
762 emit_store_dst(jd, iptr, d);
765 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
767 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
768 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
769 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
770 M_AND_IMM(s2, 0x1f, REG_ITMP3);
771 M_SLL(s1, REG_ITMP3, d);
772 M_IADD(d, REG_ZERO, d);
773 emit_store_dst(jd, iptr, d);
776 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
777 /* sx.val.i = constant */
779 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
780 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
781 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
782 M_IADD(d, REG_ZERO, d);
783 emit_store_dst(jd, iptr, d);
786 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
788 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
789 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791 M_AND_IMM(s2, 0x1f, REG_ITMP3);
792 M_SRA(s1, REG_ITMP3, d);
793 emit_store_dst(jd, iptr, d);
796 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
797 /* sx.val.i = constant */
799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
800 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
801 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
802 emit_store_dst(jd, iptr, d);
805 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
807 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
808 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
809 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
810 M_AND_IMM(s2, 0x1f, REG_ITMP2);
812 M_SRL(d, REG_ITMP2, d);
813 M_IADD(d, REG_ZERO, d);
814 emit_store_dst(jd, iptr, d);
817 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
818 /* sx.val.i = constant */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
823 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
824 M_IADD(d, REG_ZERO, d);
825 emit_store_dst(jd, iptr, d);
828 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
830 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
831 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
834 emit_store_dst(jd, iptr, d);
837 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
838 /* sx.val.i = constant */
840 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
842 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
843 emit_store_dst(jd, iptr, d);
846 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852 emit_store_dst(jd, iptr, d);
855 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
856 /* sx.val.i = constant */
858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
866 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
867 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
870 emit_store_dst(jd, iptr, d);
873 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
874 /* sx.val.i = constant */
876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
879 emit_store_dst(jd, iptr, d);
882 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
887 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
889 emit_store_dst(jd, iptr, d);
892 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
893 /* sx.val.i = constant */
895 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
896 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
897 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
898 M_AND_IMM(s1, iptr->sx.val.i, d);
899 } else if (iptr->sx.val.i == 0xffff) {
901 } else if (iptr->sx.val.i == 0xffffff) {
902 M_ZAPNOT_IMM(s1, 0x07, d);
904 ICONST(REG_ITMP2, iptr->sx.val.i);
905 M_AND(s1, REG_ITMP2, d);
907 emit_store_dst(jd, iptr, d);
910 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
911 /* sx.val.i = constant */
913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
914 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
916 M_MOV(s1, REG_ITMP1);
919 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
920 M_AND_IMM(s1, iptr->sx.val.i, d);
922 M_ISUB(REG_ZERO, s1, d);
923 M_AND_IMM(d, iptr->sx.val.i, d);
924 } else if (iptr->sx.val.i == 0xffff) {
927 M_ISUB(REG_ZERO, s1, d);
929 } else if (iptr->sx.val.i == 0xffffff) {
930 M_ZAPNOT_IMM(s1, 0x07, d);
932 M_ISUB(REG_ZERO, s1, d);
933 M_ZAPNOT_IMM(d, 0x07, d);
935 ICONST(REG_ITMP2, iptr->sx.val.i);
936 M_AND(s1, REG_ITMP2, d);
938 M_ISUB(REG_ZERO, s1, d);
939 M_AND(d, REG_ITMP2, d);
941 M_ISUB(REG_ZERO, d, d);
942 emit_store_dst(jd, iptr, d);
945 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
946 /* sx.val.l = constant */
948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
950 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
951 M_AND_IMM(s1, iptr->sx.val.l, d);
952 } else if (iptr->sx.val.l == 0xffffL) {
954 } else if (iptr->sx.val.l == 0xffffffL) {
955 M_ZAPNOT_IMM(s1, 0x07, d);
956 } else if (iptr->sx.val.l == 0xffffffffL) {
958 } else if (iptr->sx.val.l == 0xffffffffffL) {
959 M_ZAPNOT_IMM(s1, 0x1f, d);
960 } else if (iptr->sx.val.l == 0xffffffffffffL) {
961 M_ZAPNOT_IMM(s1, 0x3f, d);
962 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
963 M_ZAPNOT_IMM(s1, 0x7f, d);
965 LCONST(REG_ITMP2, iptr->sx.val.l);
966 M_AND(s1, REG_ITMP2, d);
968 emit_store_dst(jd, iptr, d);
971 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
972 /* sx.val.l = constant */
974 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
975 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
977 M_MOV(s1, REG_ITMP1);
980 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
981 M_AND_IMM(s1, iptr->sx.val.l, d);
983 M_LSUB(REG_ZERO, s1, d);
984 M_AND_IMM(d, iptr->sx.val.l, d);
985 } else if (iptr->sx.val.l == 0xffffL) {
988 M_LSUB(REG_ZERO, s1, d);
990 } else if (iptr->sx.val.l == 0xffffffL) {
991 M_ZAPNOT_IMM(s1, 0x07, d);
993 M_LSUB(REG_ZERO, s1, d);
994 M_ZAPNOT_IMM(d, 0x07, d);
995 } else if (iptr->sx.val.l == 0xffffffffL) {
998 M_LSUB(REG_ZERO, s1, d);
1000 } else if (iptr->sx.val.l == 0xffffffffffL) {
1001 M_ZAPNOT_IMM(s1, 0x1f, d);
1003 M_LSUB(REG_ZERO, s1, d);
1004 M_ZAPNOT_IMM(d, 0x1f, d);
1005 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1006 M_ZAPNOT_IMM(s1, 0x3f, d);
1008 M_LSUB(REG_ZERO, s1, d);
1009 M_ZAPNOT_IMM(d, 0x3f, d);
1010 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1011 M_ZAPNOT_IMM(s1, 0x7f, d);
1013 M_LSUB(REG_ZERO, s1, d);
1014 M_ZAPNOT_IMM(d, 0x7f, d);
1016 LCONST(REG_ITMP2, iptr->sx.val.l);
1017 M_AND(s1, REG_ITMP2, d);
1019 M_LSUB(REG_ZERO, s1, d);
1020 M_AND(d, REG_ITMP2, d);
1022 M_LSUB(REG_ZERO, d, d);
1023 emit_store_dst(jd, iptr, d);
1026 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1030 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1031 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1033 emit_store_dst(jd, iptr, d);
1036 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1037 /* sx.val.i = constant */
1039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1041 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1042 M_OR_IMM(s1, iptr->sx.val.i, d);
1044 ICONST(REG_ITMP2, iptr->sx.val.i);
1045 M_OR(s1, REG_ITMP2, d);
1047 emit_store_dst(jd, iptr, d);
1050 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1051 /* sx.val.l = constant */
1053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1055 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1056 M_OR_IMM(s1, iptr->sx.val.l, d);
1058 LCONST(REG_ITMP2, iptr->sx.val.l);
1059 M_OR(s1, REG_ITMP2, d);
1061 emit_store_dst(jd, iptr, d);
1064 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1068 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1069 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1075 /* sx.val.i = constant */
1077 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1078 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1079 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1080 M_XOR_IMM(s1, iptr->sx.val.i, d);
1082 ICONST(REG_ITMP2, iptr->sx.val.i);
1083 M_XOR(s1, REG_ITMP2, d);
1085 emit_store_dst(jd, iptr, d);
1088 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1089 /* sx.val.l = constant */
1091 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1093 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1094 M_XOR_IMM(s1, iptr->sx.val.l, d);
1096 LCONST(REG_ITMP2, iptr->sx.val.l);
1097 M_XOR(s1, REG_ITMP2, d);
1099 emit_store_dst(jd, iptr, d);
1103 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1105 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1106 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1107 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1108 M_CMPLT(s1, s2, REG_ITMP3);
1109 M_CMPLT(s2, s1, REG_ITMP1);
1110 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1111 emit_store_dst(jd, iptr, d);
1115 /* floating operations ************************************************/
1117 case ICMD_FNEG: /* ..., value ==> ..., - value */
1119 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1120 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1122 emit_store_dst(jd, iptr, d);
1125 case ICMD_DNEG: /* ..., value ==> ..., - value */
1127 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1128 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1130 emit_store_dst(jd, iptr, d);
1133 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1135 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1136 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1137 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1141 if (d == s1 || d == s2) {
1142 M_FADDS(s1, s2, REG_FTMP3);
1144 M_FMOV(REG_FTMP3, d);
1150 emit_store_dst(jd, iptr, d);
1153 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1155 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1156 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1157 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1161 if (d == s1 || d == s2) {
1162 M_DADDS(s1, s2, REG_FTMP3);
1164 M_FMOV(REG_FTMP3, d);
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1175 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1181 if (d == s1 || d == s2) {
1182 M_FSUBS(s1, s2, REG_FTMP3);
1184 M_FMOV(REG_FTMP3, d);
1190 emit_store_dst(jd, iptr, d);
1193 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1195 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1196 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1197 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1201 if (d == s1 || d == s2) {
1202 M_DSUBS(s1, s2, REG_FTMP3);
1204 M_FMOV(REG_FTMP3, d);
1210 emit_store_dst(jd, iptr, d);
1213 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1215 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1216 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1217 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1221 if (d == s1 || d == s2) {
1222 M_FMULS(s1, s2, REG_FTMP3);
1224 M_FMOV(REG_FTMP3, d);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1235 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1236 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1237 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1241 if (d == s1 || d == s2) {
1242 M_DMULS(s1, s2, REG_FTMP3);
1244 M_FMOV(REG_FTMP3, d);
1250 emit_store_dst(jd, iptr, d);
1253 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1255 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1256 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1257 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1261 if (d == s1 || d == s2) {
1262 M_FDIVS(s1, s2, REG_FTMP3);
1264 M_FMOV(REG_FTMP3, d);
1270 emit_store_dst(jd, iptr, d);
1273 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1275 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1276 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1277 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1281 if (d == s1 || d == s2) {
1282 M_DDIVS(s1, s2, REG_FTMP3);
1284 M_FMOV(REG_FTMP3, d);
1290 emit_store_dst(jd, iptr, d);
1293 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1295 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1296 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1297 disp = dseg_add_unique_double(cd, 0.0);
1298 M_LST(s1, REG_PV, disp);
1299 M_DLD(d, REG_PV, disp);
1301 emit_store_dst(jd, iptr, d);
1304 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1307 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1308 disp = dseg_add_unique_double(cd, 0.0);
1309 M_LST(s1, REG_PV, disp);
1310 M_DLD(d, REG_PV, disp);
1312 emit_store_dst(jd, iptr, d);
1315 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1317 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1318 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1319 disp = dseg_add_unique_double(cd, 0.0);
1320 M_CVTDL_C(s1, REG_FTMP2);
1321 M_CVTLI(REG_FTMP2, REG_FTMP3);
1322 M_DST(REG_FTMP3, REG_PV, disp);
1323 M_ILD(d, REG_PV, disp);
1324 emit_store_dst(jd, iptr, d);
1327 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1329 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1330 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1331 disp = dseg_add_unique_double(cd, 0.0);
1332 M_CVTDL_C(s1, REG_FTMP2);
1333 M_DST(REG_FTMP2, REG_PV, disp);
1334 M_LLD(d, REG_PV, disp);
1335 emit_store_dst(jd, iptr, d);
1338 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1340 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1341 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1344 emit_store_dst(jd, iptr, d);
1347 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1349 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1350 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1357 emit_store_dst(jd, iptr, d);
1360 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1362 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1363 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1366 M_LSUB_IMM(REG_ZERO, 1, d);
1367 M_FCMPEQ(s1, s2, REG_FTMP3);
1368 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1370 M_FCMPLT(s2, s1, REG_FTMP3);
1371 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1372 M_LADD_IMM(REG_ZERO, 1, d);
1374 M_LSUB_IMM(REG_ZERO, 1, d);
1375 M_FCMPEQS(s1, s2, REG_FTMP3);
1377 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1379 M_FCMPLTS(s2, s1, REG_FTMP3);
1381 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1382 M_LADD_IMM(REG_ZERO, 1, d);
1384 emit_store_dst(jd, iptr, d);
1387 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1389 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1390 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1391 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1393 M_LADD_IMM(REG_ZERO, 1, d);
1394 M_FCMPEQ(s1, s2, REG_FTMP3);
1395 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1397 M_FCMPLT(s1, s2, REG_FTMP3);
1398 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1399 M_LSUB_IMM(REG_ZERO, 1, d);
1401 M_LADD_IMM(REG_ZERO, 1, d);
1402 M_FCMPEQS(s1, s2, REG_FTMP3);
1404 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1406 M_FCMPLTS(s1, s2, REG_FTMP3);
1408 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1409 M_LSUB_IMM(REG_ZERO, 1, d);
1411 emit_store_dst(jd, iptr, d);
1415 /* memory operations **************************************************/
1417 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1420 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1421 /* implicit null-pointer check */
1422 M_ILD(d, s1, OFFSET(java_array_t, size));
1423 emit_store_dst(jd, iptr, d);
1426 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1428 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1429 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1431 /* implicit null-pointer check */
1432 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1433 if (has_ext_instr_set) {
1434 M_LADD(s2, s1, REG_ITMP1);
1435 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1439 M_LADD(s2, s1, REG_ITMP1);
1440 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1441 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0])+1);
1442 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1443 M_SRA_IMM(d, 56, d);
1445 emit_store_dst(jd, iptr, d);
1448 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1451 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1453 /* implicit null-pointer check */
1454 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1455 if (has_ext_instr_set) {
1456 M_LADD(s2, s1, REG_ITMP1);
1457 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1458 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1461 M_LADD (s2, s1, REG_ITMP1);
1462 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1463 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1464 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1465 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1467 emit_store_dst(jd, iptr, d);
1470 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1473 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1474 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1475 /* implicit null-pointer check */
1476 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1477 if (has_ext_instr_set) {
1478 M_LADD(s2, s1, REG_ITMP1);
1479 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1480 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1483 M_LADD(s2, s1, REG_ITMP1);
1484 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1485 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1486 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0])+2);
1487 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1488 M_SRA_IMM(d, 48, d);
1490 emit_store_dst(jd, iptr, d);
1493 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1496 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1497 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1498 /* implicit null-pointer check */
1499 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1500 M_S4ADDQ(s2, s1, REG_ITMP1);
1501 M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1502 emit_store_dst(jd, iptr, d);
1505 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1507 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1508 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1510 /* implicit null-pointer check */
1511 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1512 M_S8ADDQ(s2, s1, REG_ITMP1);
1513 M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1514 emit_store_dst(jd, iptr, d);
1517 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1520 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1521 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1522 /* implicit null-pointer check */
1523 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1524 M_S4ADDQ(s2, s1, REG_ITMP1);
1525 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1526 emit_store_dst(jd, iptr, d);
1529 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1533 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1534 /* implicit null-pointer check */
1535 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1536 M_S8ADDQ(s2, s1, REG_ITMP1);
1537 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1538 emit_store_dst(jd, iptr, d);
1541 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1544 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1545 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1546 /* implicit null-pointer check */
1547 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1548 M_SAADDQ(s2, s1, REG_ITMP1);
1549 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1550 emit_store_dst(jd, iptr, d);
1554 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1556 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1557 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1558 /* implicit null-pointer check */
1559 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1560 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1561 if (has_ext_instr_set) {
1562 M_LADD(s2, s1, REG_ITMP1);
1563 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1566 M_LADD(s2, s1, REG_ITMP1);
1567 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1568 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1569 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1570 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1571 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1572 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1576 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1579 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1580 /* implicit null-pointer check */
1581 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1582 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1583 if (has_ext_instr_set) {
1584 M_LADD(s2, s1, REG_ITMP1);
1585 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1586 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1589 M_LADD(s2, s1, REG_ITMP1);
1590 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1591 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1592 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1593 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1594 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1595 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1596 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1600 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1602 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1603 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1604 /* implicit null-pointer check */
1605 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1606 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1607 if (has_ext_instr_set) {
1608 M_LADD(s2, s1, REG_ITMP1);
1609 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1610 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1613 M_LADD(s2, s1, REG_ITMP1);
1614 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1615 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1616 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1617 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1618 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1619 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1620 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1624 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1627 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1628 /* implicit null-pointer check */
1629 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1630 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1631 M_S4ADDQ(s2, s1, REG_ITMP1);
1632 M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1635 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1639 /* implicit null-pointer check */
1640 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1641 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1642 M_S8ADDQ(s2, s1, REG_ITMP1);
1643 M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1646 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1649 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1650 /* implicit null-pointer check */
1651 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1652 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1653 M_S4ADDQ(s2, s1, REG_ITMP1);
1654 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1657 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1660 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1661 /* implicit null-pointer check */
1662 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1663 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1664 M_S8ADDQ(s2, s1, REG_ITMP1);
1665 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1668 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1670 s1 = emit_load_s1(jd, iptr, REG_A0);
1671 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1672 /* implicit null-pointer check */
1673 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1674 s3 = emit_load_s3(jd, iptr, REG_A1);
1676 M_INTMOVE(s1, REG_A0);
1677 M_INTMOVE(s3, REG_A1);
1679 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1680 M_ALD(REG_PV, REG_PV, disp);
1681 M_JSR(REG_RA, REG_PV);
1682 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1683 M_LDA(REG_PV, REG_RA, -disp);
1684 emit_exception_check(cd, iptr);
1686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1688 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1689 M_SAADDQ(s2, s1, REG_ITMP1);
1690 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1694 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1698 /* implicit null-pointer check */
1699 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1700 if (has_ext_instr_set) {
1701 M_LADD(s2, s1, REG_ITMP1);
1702 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1705 M_LADD(s2, s1, REG_ITMP1);
1706 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1707 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1708 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1709 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1710 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1711 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1715 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1718 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1719 /* implicit null-pointer check */
1720 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1721 if (has_ext_instr_set) {
1722 M_LADD(s2, s1, REG_ITMP1);
1723 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1724 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1727 M_LADD(s2, s1, REG_ITMP1);
1728 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1729 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1730 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1731 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1732 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1733 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1734 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1738 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1741 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1742 /* implicit null-pointer check */
1743 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1744 if (has_ext_instr_set) {
1745 M_LADD(s2, s1, REG_ITMP1);
1746 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1747 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1750 M_LADD(s2, s1, REG_ITMP1);
1751 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1752 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1753 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1754 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1755 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1756 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1757 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1761 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1764 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1765 /* implicit null-pointer check */
1766 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1767 M_S4ADDQ(s2, s1, REG_ITMP1);
1768 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1771 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1774 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1775 /* implicit null-pointer check */
1776 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1777 M_S8ADDQ(s2, s1, REG_ITMP1);
1778 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1781 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1785 /* implicit null-pointer check */
1786 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1787 M_SAADDQ(s2, s1, REG_ITMP1);
1788 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1792 case ICMD_GETSTATIC: /* ... ==> ..., value */
1794 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1795 uf = iptr->sx.s23.s3.uf;
1796 fieldtype = uf->fieldref->parseddesc.fd->type;
1797 disp = dseg_add_unique_address(cd, uf);
1799 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1802 fi = iptr->sx.s23.s3.fmiref->p.field;
1803 fieldtype = fi->type;
1804 disp = dseg_add_address(cd, fi->value);
1806 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1807 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1811 M_ALD(REG_ITMP1, REG_PV, disp);
1812 switch (fieldtype) {
1814 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1815 M_ILD(d, REG_ITMP1, 0);
1818 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1819 M_LLD(d, REG_ITMP1, 0);
1822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1823 M_ALD(d, REG_ITMP1, 0);
1826 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1827 M_FLD(d, REG_ITMP1, 0);
1830 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1831 M_DLD(d, REG_ITMP1, 0);
1834 emit_store_dst(jd, iptr, d);
1837 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1839 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1840 uf = iptr->sx.s23.s3.uf;
1841 fieldtype = uf->fieldref->parseddesc.fd->type;
1842 disp = dseg_add_unique_address(cd, uf);
1844 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1847 fi = iptr->sx.s23.s3.fmiref->p.field;
1848 fieldtype = fi->type;
1849 disp = dseg_add_address(cd, fi->value);
1851 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1852 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1856 M_ALD(REG_ITMP1, REG_PV, disp);
1857 switch (fieldtype) {
1859 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1860 M_IST(s1, REG_ITMP1, 0);
1863 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1864 M_LST(s1, REG_ITMP1, 0);
1867 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1868 M_AST(s1, REG_ITMP1, 0);
1871 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1872 M_FST(s1, REG_ITMP1, 0);
1875 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1876 M_DST(s1, REG_ITMP1, 0);
1881 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1882 /* val = value (in current instruction) */
1883 /* following NOP) */
1885 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1886 uf = iptr->sx.s23.s3.uf;
1887 fieldtype = uf->fieldref->parseddesc.fd->type;
1888 disp = dseg_add_unique_address(cd, uf);
1890 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1893 fi = iptr->sx.s23.s3.fmiref->p.field;
1894 fieldtype = fi->type;
1895 disp = dseg_add_address(cd, fi->value);
1897 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1898 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1902 M_ALD(REG_ITMP1, REG_PV, disp);
1903 switch (fieldtype) {
1905 M_IST(REG_ZERO, REG_ITMP1, 0);
1908 M_LST(REG_ZERO, REG_ITMP1, 0);
1911 M_AST(REG_ZERO, REG_ITMP1, 0);
1914 M_FST(REG_ZERO, REG_ITMP1, 0);
1917 M_DST(REG_ZERO, REG_ITMP1, 0);
1923 case ICMD_GETFIELD: /* ... ==> ..., value */
1925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1927 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1928 uf = iptr->sx.s23.s3.uf;
1929 fieldtype = uf->fieldref->parseddesc.fd->type;
1932 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1935 fi = iptr->sx.s23.s3.fmiref->p.field;
1936 fieldtype = fi->type;
1940 /* implicit null-pointer check */
1941 switch (fieldtype) {
1943 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1947 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1951 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1955 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1959 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1963 emit_store_dst(jd, iptr, d);
1966 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1970 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1971 uf = iptr->sx.s23.s3.uf;
1972 fieldtype = uf->fieldref->parseddesc.fd->type;
1977 fi = iptr->sx.s23.s3.fmiref->p.field;
1978 fieldtype = fi->type;
1982 if (IS_INT_LNG_TYPE(fieldtype))
1983 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1985 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1987 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1988 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1990 /* implicit null-pointer check */
1991 switch (fieldtype) {
1993 M_IST(s2, s1, disp);
1996 M_LST(s2, s1, disp);
1999 M_AST(s2, s1, disp);
2002 M_FST(s2, s1, disp);
2005 M_DST(s2, s1, disp);
2010 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2011 /* val = value (in current instruction) */
2012 /* following NOP) */
2014 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2016 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2017 uf = iptr->sx.s23.s3.uf;
2018 fieldtype = uf->fieldref->parseddesc.fd->type;
2021 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2024 fi = iptr->sx.s23.s3.fmiref->p.field;
2025 fieldtype = fi->type;
2029 /* implicit null-pointer check */
2030 switch (fieldtype) {
2032 M_IST(REG_ZERO, s1, disp);
2035 M_LST(REG_ZERO, s1, disp);
2038 M_AST(REG_ZERO, s1, disp);
2041 M_FST(REG_ZERO, s1, disp);
2044 M_DST(REG_ZERO, s1, disp);
2050 /* branch operations **************************************************/
2052 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2055 M_INTMOVE(s1, REG_ITMP1_XPTR);
2057 #ifdef ENABLE_VERIFIER
2058 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2059 unresolved_class *uc = iptr->sx.s23.s2.uc;
2061 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2063 #endif /* ENABLE_VERIFIER */
2065 disp = dseg_add_functionptr(cd, asm_handle_exception);
2066 M_ALD(REG_ITMP2, REG_PV, disp);
2067 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2068 M_NOP; /* nop ensures that XPC is less than the end */
2069 /* of basic block */
2073 case ICMD_GOTO: /* ... ==> ... */
2074 case ICMD_RET: /* ... ==> ... */
2076 emit_br(cd, iptr->dst.block);
2080 case ICMD_JSR: /* ... ==> ... */
2082 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2086 case ICMD_IFNULL: /* ..., value ==> ... */
2087 case ICMD_IFNONNULL:
2089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2090 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2093 case ICMD_IFEQ: /* ..., value ==> ... */
2095 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2096 if (iptr->sx.val.i == 0)
2097 emit_beqz(cd, iptr->dst.block, s1);
2099 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2100 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2102 ICONST(REG_ITMP2, iptr->sx.val.i);
2103 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2105 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2109 case ICMD_IFLT: /* ..., value ==> ... */
2111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2112 if (iptr->sx.val.i == 0)
2113 emit_bltz(cd, iptr->dst.block, s1);
2115 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2116 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2118 ICONST(REG_ITMP2, iptr->sx.val.i);
2119 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2121 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2125 case ICMD_IFLE: /* ..., value ==> ... */
2127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2128 if (iptr->sx.val.i == 0)
2129 emit_blez(cd, iptr->dst.block, s1);
2131 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2132 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2134 ICONST(REG_ITMP2, iptr->sx.val.i);
2135 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2137 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2141 case ICMD_IFNE: /* ..., value ==> ... */
2143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2144 if (iptr->sx.val.i == 0)
2145 emit_bnez(cd, iptr->dst.block, s1);
2147 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2148 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2150 ICONST(REG_ITMP2, iptr->sx.val.i);
2151 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2153 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2157 case ICMD_IFGT: /* ..., value ==> ... */
2159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2160 if (iptr->sx.val.i == 0)
2161 emit_bgtz(cd, iptr->dst.block, s1);
2163 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2164 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2166 ICONST(REG_ITMP2, iptr->sx.val.i);
2167 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2169 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2173 case ICMD_IFGE: /* ..., value ==> ... */
2175 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2176 if (iptr->sx.val.i == 0)
2177 emit_bgez(cd, iptr->dst.block, s1);
2179 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2180 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2182 ICONST(REG_ITMP2, iptr->sx.val.i);
2183 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2185 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2189 case ICMD_IF_LEQ: /* ..., value ==> ... */
2191 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2192 if (iptr->sx.val.l == 0)
2193 emit_beqz(cd, iptr->dst.block, s1);
2195 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2196 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2198 LCONST(REG_ITMP2, iptr->sx.val.l);
2199 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2201 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2205 case ICMD_IF_LLT: /* ..., value ==> ... */
2207 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2208 if (iptr->sx.val.l == 0)
2209 emit_bltz(cd, iptr->dst.block, s1);
2211 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2212 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2214 LCONST(REG_ITMP2, iptr->sx.val.l);
2215 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2217 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2221 case ICMD_IF_LLE: /* ..., value ==> ... */
2223 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2224 if (iptr->sx.val.l == 0)
2225 emit_blez(cd, iptr->dst.block, s1);
2227 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2228 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2230 LCONST(REG_ITMP2, iptr->sx.val.l);
2231 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2233 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2237 case ICMD_IF_LNE: /* ..., value ==> ... */
2239 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2240 if (iptr->sx.val.l == 0)
2241 emit_bnez(cd, iptr->dst.block, s1);
2243 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2244 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2246 LCONST(REG_ITMP2, iptr->sx.val.l);
2247 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2249 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2253 case ICMD_IF_LGT: /* ..., value ==> ... */
2255 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2256 if (iptr->sx.val.l == 0)
2257 emit_bgtz(cd, iptr->dst.block, s1);
2259 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2260 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2262 LCONST(REG_ITMP2, iptr->sx.val.l);
2263 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2265 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2269 case ICMD_IF_LGE: /* ..., value ==> ... */
2271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2272 if (iptr->sx.val.l == 0)
2273 emit_bgez(cd, iptr->dst.block, s1);
2275 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2276 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2278 LCONST(REG_ITMP2, iptr->sx.val.l);
2279 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2281 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2285 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2286 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2287 case ICMD_IF_ACMPEQ:
2289 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2290 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2291 M_CMPEQ(s1, s2, REG_ITMP1);
2292 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2295 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2296 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2297 case ICMD_IF_ACMPNE:
2299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2300 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2301 M_CMPEQ(s1, s2, REG_ITMP1);
2302 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2305 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2306 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2309 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2310 M_CMPLT(s1, s2, REG_ITMP1);
2311 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2314 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2315 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2317 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2318 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2319 M_CMPLE(s1, s2, REG_ITMP1);
2320 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2323 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2324 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2326 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2327 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2328 M_CMPLE(s1, s2, REG_ITMP1);
2329 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2332 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2333 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2335 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2336 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2337 M_CMPLT(s1, s2, REG_ITMP1);
2338 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2342 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2345 REPLACEMENT_POINT_RETURN(cd, iptr);
2346 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2347 M_INTMOVE(s1, REG_RESULT);
2348 goto nowperformreturn;
2350 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2352 REPLACEMENT_POINT_RETURN(cd, iptr);
2353 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2354 M_INTMOVE(s1, REG_RESULT);
2356 #ifdef ENABLE_VERIFIER
2357 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2358 unresolved_class *uc = iptr->sx.s23.s2.uc;
2360 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2362 #endif /* ENABLE_VERIFIER */
2363 goto nowperformreturn;
2365 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2368 REPLACEMENT_POINT_RETURN(cd, iptr);
2369 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2370 M_FLTMOVE(s1, REG_FRESULT);
2371 goto nowperformreturn;
2373 case ICMD_RETURN: /* ... ==> ... */
2375 REPLACEMENT_POINT_RETURN(cd, iptr);
2381 p = cd->stackframesize;
2383 /* call trace function */
2385 #if !defined(NDEBUG)
2386 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2387 emit_verbosecall_exit(jd);
2390 #if defined(ENABLE_THREADS)
2391 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2392 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2394 switch (iptr->opc) {
2398 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2402 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2406 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2407 M_ALD(REG_PV, REG_PV, disp);
2408 M_JSR(REG_RA, REG_PV);
2409 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2410 M_LDA(REG_PV, REG_RA, disp);
2412 switch (iptr->opc) {
2416 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2420 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2426 /* restore return address */
2428 if (!jd->isleafmethod) {
2429 p--; M_LLD(REG_RA, REG_SP, p * 8);
2432 /* restore saved registers */
2434 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2435 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2437 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2438 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2441 /* deallocate stack */
2443 if (cd->stackframesize)
2444 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2446 M_RET(REG_ZERO, REG_RA);
2452 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2455 branch_target_t *table;
2457 table = iptr->dst.table;
2459 l = iptr->sx.s23.s2.tablelow;
2460 i = iptr->sx.s23.s3.tablehigh;
2462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2464 M_INTMOVE(s1, REG_ITMP1);
2465 } else if (l <= 32768) {
2466 M_LDA(REG_ITMP1, s1, -l);
2468 ICONST(REG_ITMP2, l);
2469 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2472 /* number of targets */
2478 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2480 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2481 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2483 emit_beqz(cd, table[0].block, REG_ITMP2);
2485 /* build jump table top down and use address of lowest entry */
2490 dseg_add_target(cd, table->block);
2495 /* length of dataseg after last dseg_add_target is used by load */
2497 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2498 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2499 M_JMP(REG_ZERO, REG_ITMP2);
2504 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2507 lookup_target_t *lookup;
2509 lookup = iptr->dst.lookup;
2511 i = iptr->sx.s23.s2.lookupcount;
2513 MCODECHECK((i<<2)+8);
2514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2517 val = lookup->value;
2518 if ((val >= 0) && (val <= 255)) {
2519 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2521 if ((val >= -32768) && (val <= 32767)) {
2522 M_LDA(REG_ITMP2, REG_ZERO, val);
2524 disp = dseg_add_s4(cd, val);
2525 M_ILD(REG_ITMP2, REG_PV, disp);
2527 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2529 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2533 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2539 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2541 bte = iptr->sx.s23.s3.bte;
2545 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2547 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2548 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2549 case ICMD_INVOKEINTERFACE:
2551 REPLACEMENT_POINT_INVOKE(cd, iptr);
2553 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2555 um = iptr->sx.s23.s3.um;
2556 md = um->methodref->parseddesc.md;
2559 lm = iptr->sx.s23.s3.fmiref->p.method;
2561 md = lm->parseddesc;
2565 s3 = md->paramcount;
2567 MCODECHECK((s3 << 1) + 64);
2569 /* copy arguments to registers or stack location */
2571 for (s3 = s3 - 1; s3 >= 0; s3--) {
2572 var = VAR(iptr->sx.s23.s2.args[s3]);
2573 d = md->params[s3].regoff;
2575 /* already preallocated (ARGVAR)? */
2577 if (var->flags & PREALLOC)
2580 if (IS_INT_LNG_TYPE(var->type)) {
2581 if (!md->params[s3].inmemory) {
2582 s1 = emit_load(jd, iptr, var, d);
2586 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2587 M_LST(s1, REG_SP, d);
2591 if (!md->params[s3].inmemory) {
2592 s1 = emit_load(jd, iptr, var, d);
2596 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2597 M_DST(s1, REG_SP, d);
2602 switch (iptr->opc) {
2604 disp = dseg_add_functionptr(cd, bte->fp);
2606 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2608 /* generate the actual call */
2610 M_JSR(REG_RA, REG_PV);
2611 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2612 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2613 M_LDA(REG_PV, REG_RA, -disp);
2615 emit_exception_check(cd, iptr);
2618 case ICMD_INVOKESPECIAL:
2619 emit_nullpointer_check(cd, iptr, REG_A0);
2622 case ICMD_INVOKESTATIC:
2624 disp = dseg_add_unique_address(cd, um);
2626 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2630 disp = dseg_add_address(cd, lm->stubroutine);
2632 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2634 /* generate the actual call */
2636 M_JSR(REG_RA, REG_PV);
2637 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2638 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2639 M_LDA(REG_PV, REG_RA, -disp);
2642 case ICMD_INVOKEVIRTUAL:
2644 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2649 s1 = OFFSET(vftbl_t, table[0]) +
2650 sizeof(methodptr) * lm->vftblindex;
2652 /* implicit null-pointer check */
2653 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2654 M_ALD(REG_PV, REG_METHODPTR, s1);
2656 /* generate the actual call */
2658 M_JSR(REG_RA, REG_PV);
2659 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2660 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2661 M_LDA(REG_PV, REG_RA, -disp);
2664 case ICMD_INVOKEINTERFACE:
2666 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2672 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2673 sizeof(methodptr*) * lm->class->index;
2675 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2678 /* implicit null-pointer check */
2679 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2680 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2681 M_ALD(REG_PV, REG_METHODPTR, s2);
2683 /* generate the actual call */
2685 M_JSR(REG_RA, REG_PV);
2686 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2687 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2688 M_LDA(REG_PV, REG_RA, -disp);
2692 /* store the return value */
2694 d = md->returntype.type;
2696 if (d != TYPE_VOID) {
2697 if (IS_INT_LNG_TYPE(d)) {
2698 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2699 M_INTMOVE(REG_RESULT, s1);
2702 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2703 M_FLTMOVE(REG_FRESULT, s1);
2705 emit_store_dst(jd, iptr, s1);
2710 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2712 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2713 /* object type cast-check */
2718 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2723 super = iptr->sx.s23.s3.c.cls;
2724 superindex = super->index;
2727 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2728 CODEGEN_CRITICAL_SECTION_NEW;
2730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2732 /* if class is not resolved, check which code to call */
2734 if (super == NULL) {
2735 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2737 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2739 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2740 iptr->sx.s23.s3.c.ref,
2743 M_ILD(REG_ITMP2, REG_PV, disp);
2744 disp = dseg_add_s4(cd, ACC_INTERFACE);
2745 M_ILD(REG_ITMP3, REG_PV, disp);
2746 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2747 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2750 /* interface checkcast code */
2752 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2753 if (super == NULL) {
2754 patcher_add_patch_ref(jd,
2755 PATCHER_checkcast_interface,
2756 iptr->sx.s23.s3.c.ref,
2760 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2762 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2763 M_ILD(REG_ITMP3, REG_ITMP2,
2764 OFFSET(vftbl_t, interfacetablelength));
2765 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2766 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2768 M_ALD(REG_ITMP3, REG_ITMP2,
2769 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2770 superindex * sizeof(methodptr*)));
2771 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2774 emit_label_br(cd, BRANCH_LABEL_4);
2776 emit_label(cd, BRANCH_LABEL_3);
2779 /* class checkcast code */
2781 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2782 if (super == NULL) {
2783 emit_label(cd, BRANCH_LABEL_2);
2785 disp = dseg_add_unique_address(cd, NULL);
2787 patcher_add_patch_ref(jd,
2788 PATCHER_resolve_classref_to_vftbl,
2789 iptr->sx.s23.s3.c.ref,
2793 disp = dseg_add_address(cd, super->vftbl);
2795 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2798 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2799 M_ALD(REG_ITMP3, REG_PV, disp);
2801 CODEGEN_CRITICAL_SECTION_START;
2803 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2804 /* if (s1 != REG_ITMP1) { */
2805 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2806 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2807 /* #if defined(ENABLE_THREADS) */
2808 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2810 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2813 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2814 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2815 M_ALD(REG_ITMP3, REG_PV, disp);
2816 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2818 CODEGEN_CRITICAL_SECTION_END;
2821 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2822 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2825 emit_label(cd, BRANCH_LABEL_5);
2828 if (super == NULL) {
2829 emit_label(cd, BRANCH_LABEL_1);
2830 emit_label(cd, BRANCH_LABEL_4);
2833 d = codegen_reg_of_dst(jd, iptr, s1);
2836 /* array type cast-check */
2838 s1 = emit_load_s1(jd, iptr, REG_A0);
2839 M_INTMOVE(s1, REG_A0);
2841 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2842 disp = dseg_add_unique_address(cd, NULL);
2844 patcher_add_patch_ref(jd,
2845 PATCHER_resolve_classref_to_classinfo,
2846 iptr->sx.s23.s3.c.ref,
2850 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2852 M_ALD(REG_A1, REG_PV, disp);
2853 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2854 M_ALD(REG_PV, REG_PV, disp);
2855 M_JSR(REG_RA, REG_PV);
2856 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2857 M_LDA(REG_PV, REG_RA, -disp);
2859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2860 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2862 d = codegen_reg_of_dst(jd, iptr, s1);
2866 emit_store_dst(jd, iptr, d);
2869 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2873 vftbl_t *supervftbl;
2876 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2882 super = iptr->sx.s23.s3.c.cls;
2883 superindex = super->index;
2884 supervftbl = super->vftbl;
2887 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2888 CODEGEN_CRITICAL_SECTION_NEW;
2890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2891 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2894 M_MOV(s1, REG_ITMP1);
2898 /* if class is not resolved, check which code to call */
2900 if (super == NULL) {
2902 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2904 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2906 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2907 iptr->sx.s23.s3.c.ref, disp);
2909 M_ILD(REG_ITMP3, REG_PV, disp);
2911 disp = dseg_add_s4(cd, ACC_INTERFACE);
2912 M_ILD(REG_ITMP2, REG_PV, disp);
2913 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2914 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2917 /* interface instanceof code */
2919 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2920 if (super == NULL) {
2921 /* If d == REG_ITMP2, then it's destroyed in check
2926 patcher_add_patch_ref(jd,
2927 PATCHER_instanceof_interface,
2928 iptr->sx.s23.s3.c.ref, 0);
2932 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2935 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2936 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2937 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2938 M_BLEZ(REG_ITMP3, 2);
2939 M_ALD(REG_ITMP1, REG_ITMP1,
2940 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2941 superindex * sizeof(methodptr*)));
2942 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2945 emit_label_br(cd, BRANCH_LABEL_4);
2947 emit_label(cd, BRANCH_LABEL_3);
2950 /* class instanceof code */
2952 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2953 if (super == NULL) {
2954 emit_label(cd, BRANCH_LABEL_2);
2956 disp = dseg_add_unique_address(cd, NULL);
2958 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2959 iptr->sx.s23.s3.c.ref,
2963 disp = dseg_add_address(cd, supervftbl);
2966 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2969 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2970 M_ALD(REG_ITMP2, REG_PV, disp);
2972 CODEGEN_CRITICAL_SECTION_START;
2974 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2975 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2976 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2978 CODEGEN_CRITICAL_SECTION_END;
2980 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2981 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
2984 emit_label(cd, BRANCH_LABEL_5);
2987 if (super == NULL) {
2988 emit_label(cd, BRANCH_LABEL_1);
2989 emit_label(cd, BRANCH_LABEL_4);
2992 emit_store_dst(jd, iptr, d);
2996 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2998 /* check for negative sizes and copy sizes to stack if necessary */
3000 MCODECHECK((iptr->s1.argcount << 1) + 64);
3002 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3004 var = VAR(iptr->sx.s23.s2.args[s1]);
3006 /* copy SAVEDVAR sizes to stack */
3008 /* Already Preallocated? */
3010 if (!(var->flags & PREALLOC)) {
3011 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3012 M_LST(s2, REG_SP, s1 * 8);
3016 /* a0 = dimension count */
3018 ICONST(REG_A0, iptr->s1.argcount);
3020 /* is patcher function set? */
3022 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3023 disp = dseg_add_unique_address(cd, 0);
3025 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3026 iptr->sx.s23.s3.c.ref,
3030 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3032 /* a1 = arraydescriptor */
3034 M_ALD(REG_A1, REG_PV, disp);
3036 /* a2 = pointer to dimensions = stack pointer */
3038 M_INTMOVE(REG_SP, REG_A2);
3040 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3041 M_ALD(REG_PV, REG_PV, disp);
3042 M_JSR(REG_RA, REG_PV);
3043 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3044 M_LDA(REG_PV, REG_RA, -disp);
3046 /* check for exception before result assignment */
3048 emit_exception_check(cd, iptr);
3050 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3051 M_INTMOVE(REG_RESULT, d);
3052 emit_store_dst(jd, iptr, d);
3056 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3061 } /* for instruction */
3063 } /* if (bptr -> flags >= BBREACHED) */
3064 } /* for basic block */
3066 dseg_createlinenumbertable(cd);
3068 /* generate traps */
3070 emit_patcher_traps(jd);
3072 /* everything's ok */
3078 /* codegen_emit_stub_compiler **************************************************
3080 Emits a stub routine which calls the compiler.
3082 *******************************************************************************/
3084 void codegen_emit_stub_compiler(jitdata *jd)
3089 /* get required compiler data */
3094 /* code for the stub */
3096 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3097 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3098 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3102 /* codegen_emit_stub_native ****************************************************
3104 Emits a stub routine which calls a native method.
3106 *******************************************************************************/
3108 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3115 s4 i, j; /* count variables */
3118 s4 funcdisp; /* displacement of the function */
3120 /* get required compiler data */
3126 /* initialize variables */
3129 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3131 /* calculate stack frame size */
3133 cd->stackframesize =
3134 1 + /* return address */
3135 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3136 sizeof(localref_table) / SIZEOF_VOID_P +
3137 1 + /* methodinfo for call trace */
3141 /* create method header */
3143 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3144 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3145 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3146 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3147 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3148 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3149 (void) dseg_addlinenumbertablesize(cd);
3150 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3152 /* generate stub code */
3154 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3155 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3157 /* call trace function */
3159 #if !defined(NDEBUG)
3160 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3161 emit_verbosecall_enter(jd);
3164 /* get function address (this must happen before the stackframeinfo) */
3166 funcdisp = dseg_add_functionptr(cd, f);
3168 #if !defined(WITH_STATIC_CLASSPATH)
3170 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3173 /* save integer and float argument registers */
3175 for (i = 0; i < md->paramcount; i++) {
3176 if (!md->params[i].inmemory) {
3177 s1 = md->params[i].regoff;
3179 switch (md->paramtypes[i].type) {
3183 M_LST(s1, REG_SP, i * 8);
3187 M_DST(s1, REG_SP, i * 8);
3193 /* prepare data structures for native function call */
3195 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3196 M_MOV(REG_PV, REG_A1);
3197 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3198 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3199 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3200 M_ALD(REG_PV, REG_PV, disp);
3201 M_JSR(REG_RA, REG_PV);
3202 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3203 M_LDA(REG_PV, REG_RA, -disp);
3205 /* restore integer and float argument registers */
3207 for (i = 0; i < md->paramcount; i++) {
3208 if (!md->params[i].inmemory) {
3209 s1 = md->params[i].regoff;
3211 switch (md->paramtypes[i].type) {
3215 M_LLD(s1, REG_SP, i * 8);
3219 M_DLD(s1, REG_SP, i * 8);
3225 /* copy or spill arguments to new locations */
3227 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3228 t = md->paramtypes[i].type;
3230 if (IS_INT_LNG_TYPE(t)) {
3231 if (!md->params[i].inmemory) {
3232 s1 = md->params[i].regoff;
3233 s2 = nmd->params[j].regoff;
3235 if (!nmd->params[j].inmemory)
3238 M_LST(s1, REG_SP, s2);
3241 s1 = md->params[i].regoff + cd->stackframesize * 8;
3242 s2 = nmd->params[j].regoff;
3243 M_LLD(REG_ITMP1, REG_SP, s1);
3244 M_LST(REG_ITMP1, REG_SP, s2);
3248 if (!md->params[i].inmemory) {
3249 s1 = md->params[i].regoff;
3250 s2 = nmd->params[j].regoff;
3252 if (!nmd->params[j].inmemory)
3255 if (IS_2_WORD_TYPE(t))
3256 M_DST(s1, REG_SP, s2);
3258 M_FST(s1, REG_SP, s2);
3262 s1 = md->params[i].regoff + cd->stackframesize * 8;
3263 s2 = nmd->params[j].regoff;
3264 M_DLD(REG_FTMP1, REG_SP, s1);
3265 if (IS_2_WORD_TYPE(t))
3266 M_DST(REG_FTMP1, REG_SP, s2);
3268 M_FST(REG_FTMP1, REG_SP, s2);
3273 /* put class into second argument register */
3275 if (m->flags & ACC_STATIC) {
3276 disp = dseg_add_address(cd, m->class);
3277 M_ALD(REG_A1, REG_PV, disp);
3280 /* put env into first argument register */
3282 disp = dseg_add_address(cd, _Jv_env);
3283 M_ALD(REG_A0, REG_PV, disp);
3285 /* do the native function call */
3287 M_ALD(REG_PV, REG_PV, funcdisp);
3288 M_JSR(REG_RA, REG_PV); /* call native method */
3289 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3290 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3292 /* save return value */
3294 switch (md->returntype.type) {
3298 M_LST(REG_RESULT, REG_SP, 0 * 8);
3302 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3308 /* call finished trace */
3310 #if !defined(NDEBUG)
3311 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3312 emit_verbosecall_exit(jd);
3315 /* remove native stackframe info */
3317 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3318 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3319 M_ALD(REG_PV, REG_PV, disp);
3320 M_JSR(REG_RA, REG_PV);
3321 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3322 M_LDA(REG_PV, REG_RA, -disp);
3323 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3325 /* restore return value */
3327 switch (md->returntype.type) {
3331 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3335 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3341 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3342 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3344 /* check for exception */
3346 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3347 M_RET(REG_ZERO, REG_RA); /* return to caller */
3349 /* handle exception */
3351 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3353 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3354 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3355 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3357 /* generate patcher stubs */
3359 emit_patcher_traps(jd);
3364 * These are local overrides for various environment variables in Emacs.
3365 * Please do not remove this and leave it at the end of the file, where
3366 * Emacs will automagically detect them.
3367 * ---------------------------------------------------------------------
3370 * indent-tabs-mode: t
3374 * vim:noexpandtab:sw=4:ts=4: