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
38 #include "vm/jit/alpha/arch.h"
39 #include "vm/jit/alpha/codegen.h"
41 #include "mm/memory.h"
43 #include "native/jni.h"
44 #include "native/localref.h"
45 #include "native/native.h"
47 #include "threads/lock-common.h"
49 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/global.h"
54 #include "vm/jit/abi.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/dseg.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/parse.h"
61 #include "vm/jit/patcher-common.h"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.h"
64 #include "vm/jit/stacktrace.h"
66 #if defined(ENABLE_LSRA)
67 # include "vm/jit/allocator/lsra.h"
70 #include "vmcore/loader.h"
71 #include "vmcore/options.h"
74 /* codegen_emit ****************************************************************
76 Generates machine code.
78 *******************************************************************************/
80 bool codegen_emit(jitdata *jd)
86 s4 len, s1, s2, s3, d, disp;
92 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
93 unresolved_method *um;
94 builtintable_entry *bte;
101 /* get required compiler data */
108 /* prevent compiler warnings */
121 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
123 /* space to save used callee saved registers */
125 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
126 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
128 cd->stackframesize = rd->memuse + savedregs_num;
130 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
131 if (checksync && (m->flags & ACC_SYNCHRONIZED))
132 cd->stackframesize++;
135 /* create method header */
138 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
141 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
142 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
144 #if defined(ENABLE_THREADS)
145 /* IsSync contains the offset relative to the stack pointer for the
146 argument of monitor_exit used in the exception handler. Since the
147 offset could be zero and give a wrong meaning of the flag it is
151 if (checksync && (m->flags & ACC_SYNCHRONIZED))
152 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
155 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
157 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
158 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
159 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
161 dseg_addlinenumbertablesize(cd);
163 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
165 /* create exception table */
167 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
168 dseg_add_target(cd, ex->start);
169 dseg_add_target(cd, ex->end);
170 dseg_add_target(cd, ex->handler);
171 (void) dseg_add_unique_address(cd, ex->catchtype.any);
174 /* create stack frame (if necessary) */
176 if (cd->stackframesize)
177 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
179 /* save return address and used callee saved registers */
181 p = cd->stackframesize;
182 if (!jd->isleafmethod) {
183 p--; M_AST(REG_RA, REG_SP, p * 8);
185 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
186 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
188 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
189 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
192 /* take arguments out of register or stack frame */
196 for (p = 0, l = 0; p < md->paramcount; p++) {
197 t = md->paramtypes[p].type;
199 varindex = jd->local_map[l * 5 + t];
202 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
205 if (varindex == UNUSED)
210 s1 = md->params[p].regoff;
212 if (IS_INT_LNG_TYPE(t)) { /* integer args */
213 if (!md->params[p].inmemory) { /* register arguments */
214 if (!IS_INMEMORY(var->flags))
215 M_INTMOVE(s1, var->vv.regoff);
217 M_LST(s1, REG_SP, var->vv.regoff);
219 else { /* stack arguments */
220 if (!IS_INMEMORY(var->flags))
221 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
223 var->vv.regoff = cd->stackframesize * 8 + s1;
226 else { /* floating args */
227 if (!md->params[p].inmemory) { /* register arguments */
228 if (!IS_INMEMORY(var->flags))
229 M_FLTMOVE(s1, var->vv.regoff);
231 M_DST(s1, REG_SP, var->vv.regoff * 8);
233 else { /* stack arguments */
234 if (!(var->flags & INMEMORY))
235 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
237 var->vv.regoff = cd->stackframesize * 8 + s1;
242 /* call monitorenter function */
244 #if defined(ENABLE_THREADS)
245 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
246 /* stack offset for monitor argument */
251 if (opt_verbosecall) {
252 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
254 for (p = 0; p < INT_ARG_CNT; p++)
255 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
257 for (p = 0; p < FLT_ARG_CNT; p++)
258 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
260 s1 += INT_ARG_CNT + FLT_ARG_CNT;
262 #endif /* !defined(NDEBUG) */
264 /* decide which monitor enter function to call */
266 if (m->flags & ACC_STATIC) {
267 disp = dseg_add_address(cd, &m->class->object.header);
268 M_ALD(REG_A0, REG_PV, disp);
272 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
275 M_AST(REG_A0, REG_SP, s1 * 8);
276 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
277 M_ALD(REG_PV, REG_PV, disp);
278 M_JSR(REG_RA, REG_PV);
279 disp = (s4) (cd->mcodeptr - cd->mcodebase);
280 M_LDA(REG_PV, REG_RA, -disp);
283 if (opt_verbosecall) {
284 for (p = 0; p < INT_ARG_CNT; p++)
285 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
287 for (p = 0; p < FLT_ARG_CNT; p++)
288 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
290 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
292 #endif /* !defined(NDEBUG) */
296 /* call trace function */
299 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
300 emit_verbosecall_enter(jd);
305 /* end of header generation */
307 /* create replacement points */
309 REPLACEMENT_POINTS_INIT(cd, jd);
311 /* walk through all basic blocks */
313 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
315 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
317 if (bptr->flags >= BBREACHED) {
319 /* branch resolving */
321 codegen_resolve_branchrefs(cd, bptr);
323 /* handle replacement points */
325 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
327 /* copy interface registers to their destination */
331 #if defined(ENABLE_LSRA)
335 src = bptr->invars[len];
336 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
337 /* d = reg_of_var(m, src, REG_ITMP1); */
338 if (!(src->flags & INMEMORY))
342 M_INTMOVE(REG_ITMP1, d);
343 emit_store(jd, NULL, src, d);
350 var = VAR(bptr->invars[len]);
351 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
352 d = codegen_reg_of_var(0, var, REG_ITMP1);
353 M_INTMOVE(REG_ITMP1, d);
354 emit_store(jd, NULL, var, d);
357 assert((var->flags & INOUT));
360 #if defined(ENABLE_LSRA)
364 /* walk through all instructions */
368 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
369 if (iptr->line != currentline) {
370 dseg_addlinenumber(cd, iptr->line);
371 currentline = iptr->line;
374 MCODECHECK(64); /* an instruction usually needs < 64 words */
377 case ICMD_NOP: /* ... ==> ... */
378 case ICMD_POP: /* ..., value ==> ... */
379 case ICMD_POP2: /* ..., value, value ==> ... */
382 case ICMD_INLINE_START:
384 REPLACEMENT_POINT_INLINE_START(cd, iptr);
387 case ICMD_INLINE_BODY:
389 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
390 dseg_addlinenumber_inline_start(cd, iptr);
391 dseg_addlinenumber(cd, iptr->line);
394 case ICMD_INLINE_END:
396 dseg_addlinenumber_inline_end(cd, iptr);
397 dseg_addlinenumber(cd, iptr->line);
400 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
403 emit_nullpointer_check(cd, iptr, s1);
406 /* constant operations ************************************************/
408 case ICMD_ICONST: /* ... ==> ..., constant */
410 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
411 ICONST(d, iptr->sx.val.i);
412 emit_store_dst(jd, iptr, d);
415 case ICMD_LCONST: /* ... ==> ..., constant */
417 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
418 LCONST(d, iptr->sx.val.l);
419 emit_store_dst(jd, iptr, d);
422 case ICMD_FCONST: /* ... ==> ..., constant */
424 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
425 disp = dseg_add_float(cd, iptr->sx.val.f);
426 M_FLD(d, REG_PV, disp);
427 emit_store_dst(jd, iptr, d);
430 case ICMD_DCONST: /* ... ==> ..., constant */
432 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
433 disp = dseg_add_double(cd, iptr->sx.val.d);
434 M_DLD(d, REG_PV, disp);
435 emit_store_dst(jd, iptr, d);
438 case ICMD_ACONST: /* ... ==> ..., constant */
440 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
442 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
443 constant_classref *cr = iptr->sx.val.c.ref;
445 disp = dseg_add_unique_address(cd, cr);
447 /* XXX Only add the patcher, if this position needs to
448 be patched. If there was a previous position which
449 resolved the same class, the returned displacement
450 of dseg_add_address is ok to use. */
452 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
455 M_ALD(d, REG_PV, disp);
458 if (iptr->sx.val.anyptr == NULL)
459 M_INTMOVE(REG_ZERO, d);
461 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
462 M_ALD(d, REG_PV, disp);
465 emit_store_dst(jd, iptr, d);
469 /* load/store/move/copy operations ************************************/
471 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
472 case ICMD_ALOAD: /* s1 = local variable */
476 case ICMD_ISTORE: /* ..., value ==> ... */
488 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
493 /* integer operations *************************************************/
495 case ICMD_INEG: /* ..., value ==> ..., - value */
497 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
499 M_ISUB(REG_ZERO, s1, d);
500 emit_store_dst(jd, iptr, d);
503 case ICMD_LNEG: /* ..., value ==> ..., - value */
505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
506 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
507 M_LSUB(REG_ZERO, s1, d);
508 emit_store_dst(jd, iptr, d);
511 case ICMD_I2L: /* ..., value ==> ..., value */
513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
514 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
516 emit_store_dst(jd, iptr, d);
519 case ICMD_L2I: /* ..., value ==> ..., value */
521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
523 M_IADD(s1, REG_ZERO, d);
524 emit_store_dst(jd, iptr, d);
527 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
531 if (has_ext_instr_set) {
534 M_SLL_IMM(s1, 56, d);
535 M_SRA_IMM( d, 56, d);
537 emit_store_dst(jd, iptr, d);
540 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
545 emit_store_dst(jd, iptr, d);
548 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
552 if (has_ext_instr_set) {
555 M_SLL_IMM(s1, 48, d);
556 M_SRA_IMM( d, 48, d);
558 emit_store_dst(jd, iptr, d);
562 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
565 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
566 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
568 emit_store_dst(jd, iptr, d);
572 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
573 /* sx.val.i = constant */
575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
577 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
578 M_IADD_IMM(s1, iptr->sx.val.i, d);
579 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
580 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
582 /* XXX maybe use M_LDA? */
583 ICONST(REG_ITMP2, iptr->sx.val.i);
584 M_IADD(s1, REG_ITMP2, d);
586 emit_store_dst(jd, iptr, d);
589 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
592 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
595 emit_store_dst(jd, iptr, d);
598 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
599 /* sx.val.l = constant */
601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
604 M_LADD_IMM(s1, iptr->sx.val.l, d);
606 LCONST(REG_ITMP2, iptr->sx.val.l);
607 M_LADD(s1, REG_ITMP2, d);
609 emit_store_dst(jd, iptr, d);
612 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
618 emit_store_dst(jd, iptr, d);
621 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
622 /* sx.val.i = constant */
624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
627 M_ISUB_IMM(s1, iptr->sx.val.i, d);
629 ICONST(REG_ITMP2, iptr->sx.val.i);
630 M_ISUB(s1, REG_ITMP2, d);
632 emit_store_dst(jd, iptr, d);
635 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 emit_store_dst(jd, iptr, d);
644 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
645 /* sx.val.l = constant */
647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
650 M_LSUB_IMM(s1, iptr->sx.val.l, d);
652 LCONST(REG_ITMP2, iptr->sx.val.l);
653 M_LSUB(s1, REG_ITMP2, d);
655 emit_store_dst(jd, iptr, d);
658 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
660 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
661 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664 emit_store_dst(jd, iptr, d);
667 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
668 /* sx.val.i = constant */
670 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
672 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
673 M_IMUL_IMM(s1, iptr->sx.val.i, d);
675 ICONST(REG_ITMP2, iptr->sx.val.i);
676 M_IMUL(s1, REG_ITMP2, d);
678 emit_store_dst(jd, iptr, d);
681 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
683 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
684 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
685 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
687 emit_store_dst(jd, iptr, d);
690 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
691 /* sx.val.l = constant */
693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
695 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
696 M_LMUL_IMM(s1, iptr->sx.val.l, d);
698 LCONST(REG_ITMP2, iptr->sx.val.l);
699 M_LMUL(s1, REG_ITMP2, d);
701 emit_store_dst(jd, iptr, d);
704 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
705 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
707 s1 = emit_load_s1(jd, iptr, REG_A0);
708 s2 = emit_load_s2(jd, iptr, REG_A1);
709 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
710 emit_arithmetic_check(cd, iptr, s2);
712 M_INTMOVE(s1, REG_A0);
713 M_INTMOVE(s2, REG_A1);
714 bte = iptr->sx.s23.s3.bte;
715 disp = dseg_add_functionptr(cd, bte->fp);
716 M_ALD(REG_PV, REG_PV, disp);
717 M_JSR(REG_RA, REG_PV);
718 disp = (s4) (cd->mcodeptr - cd->mcodebase);
719 M_LDA(REG_PV, REG_RA, -disp);
721 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
722 emit_store_dst(jd, iptr, d);
725 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
726 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
728 s1 = emit_load_s1(jd, iptr, REG_A0);
729 s2 = emit_load_s2(jd, iptr, REG_A1);
730 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
731 emit_arithmetic_check(cd, iptr, s2);
733 M_INTMOVE(s1, REG_A0);
734 M_INTMOVE(s2, REG_A1);
735 bte = iptr->sx.s23.s3.bte;
736 disp = dseg_add_functionptr(cd, bte->fp);
737 M_ALD(REG_PV, REG_PV, disp);
738 M_JSR(REG_RA, REG_PV);
739 disp = (s4) (cd->mcodeptr - cd->mcodebase);
740 M_LDA(REG_PV, REG_RA, -disp);
742 M_INTMOVE(REG_RESULT, d);
743 emit_store_dst(jd, iptr, d);
746 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
747 case ICMD_LDIVPOW2: /* val.i = constant */
749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
751 if (iptr->sx.val.i <= 15) {
752 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
753 M_CMOVGE(s1, s1, REG_ITMP2);
755 M_SRA_IMM(s1, 63, REG_ITMP2);
756 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
757 M_LADD(s1, REG_ITMP2, REG_ITMP2);
759 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
760 emit_store_dst(jd, iptr, d);
763 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
768 M_AND_IMM(s2, 0x1f, REG_ITMP3);
769 M_SLL(s1, REG_ITMP3, d);
770 M_IADD(d, REG_ZERO, d);
771 emit_store_dst(jd, iptr, d);
774 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
775 /* sx.val.i = constant */
777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
778 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
779 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
780 M_IADD(d, REG_ZERO, d);
781 emit_store_dst(jd, iptr, d);
784 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
786 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
787 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
789 M_AND_IMM(s2, 0x1f, REG_ITMP3);
790 M_SRA(s1, REG_ITMP3, d);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
795 /* sx.val.i = constant */
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
799 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
800 emit_store_dst(jd, iptr, d);
803 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
807 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
808 M_AND_IMM(s2, 0x1f, REG_ITMP2);
810 M_SRL(d, REG_ITMP2, d);
811 M_IADD(d, REG_ZERO, d);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
816 /* sx.val.i = constant */
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
822 M_IADD(d, REG_ZERO, d);
823 emit_store_dst(jd, iptr, d);
826 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
828 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
829 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
830 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
836 /* sx.val.i = constant */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
840 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
841 emit_store_dst(jd, iptr, d);
844 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
847 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
848 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
850 emit_store_dst(jd, iptr, d);
853 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
854 /* sx.val.i = constant */
856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
858 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
859 emit_store_dst(jd, iptr, d);
862 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 emit_store_dst(jd, iptr, d);
871 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
872 /* sx.val.i = constant */
874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
877 emit_store_dst(jd, iptr, d);
880 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
887 emit_store_dst(jd, iptr, d);
890 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
891 /* sx.val.i = constant */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
896 M_AND_IMM(s1, iptr->sx.val.i, d);
897 } else if (iptr->sx.val.i == 0xffff) {
899 } else if (iptr->sx.val.i == 0xffffff) {
900 M_ZAPNOT_IMM(s1, 0x07, d);
902 ICONST(REG_ITMP2, iptr->sx.val.i);
903 M_AND(s1, REG_ITMP2, d);
905 emit_store_dst(jd, iptr, d);
908 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
909 /* sx.val.i = constant */
911 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
914 M_MOV(s1, REG_ITMP1);
917 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
918 M_AND_IMM(s1, iptr->sx.val.i, d);
920 M_ISUB(REG_ZERO, s1, d);
921 M_AND_IMM(d, iptr->sx.val.i, d);
922 } else if (iptr->sx.val.i == 0xffff) {
925 M_ISUB(REG_ZERO, s1, d);
927 } else if (iptr->sx.val.i == 0xffffff) {
928 M_ZAPNOT_IMM(s1, 0x07, d);
930 M_ISUB(REG_ZERO, s1, d);
931 M_ZAPNOT_IMM(d, 0x07, d);
933 ICONST(REG_ITMP2, iptr->sx.val.i);
934 M_AND(s1, REG_ITMP2, d);
936 M_ISUB(REG_ZERO, s1, d);
937 M_AND(d, REG_ITMP2, d);
939 M_ISUB(REG_ZERO, d, d);
940 emit_store_dst(jd, iptr, d);
943 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
944 /* sx.val.l = constant */
946 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
947 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
948 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
949 M_AND_IMM(s1, iptr->sx.val.l, d);
950 } else if (iptr->sx.val.l == 0xffffL) {
952 } else if (iptr->sx.val.l == 0xffffffL) {
953 M_ZAPNOT_IMM(s1, 0x07, d);
954 } else if (iptr->sx.val.l == 0xffffffffL) {
956 } else if (iptr->sx.val.l == 0xffffffffffL) {
957 M_ZAPNOT_IMM(s1, 0x1f, d);
958 } else if (iptr->sx.val.l == 0xffffffffffffL) {
959 M_ZAPNOT_IMM(s1, 0x3f, d);
960 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
961 M_ZAPNOT_IMM(s1, 0x7f, d);
963 LCONST(REG_ITMP2, iptr->sx.val.l);
964 M_AND(s1, REG_ITMP2, d);
966 emit_store_dst(jd, iptr, d);
969 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
970 /* sx.val.l = constant */
972 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
973 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
975 M_MOV(s1, REG_ITMP1);
978 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
979 M_AND_IMM(s1, iptr->sx.val.l, d);
981 M_LSUB(REG_ZERO, s1, d);
982 M_AND_IMM(d, iptr->sx.val.l, d);
983 } else if (iptr->sx.val.l == 0xffffL) {
986 M_LSUB(REG_ZERO, s1, d);
988 } else if (iptr->sx.val.l == 0xffffffL) {
989 M_ZAPNOT_IMM(s1, 0x07, d);
991 M_LSUB(REG_ZERO, s1, d);
992 M_ZAPNOT_IMM(d, 0x07, d);
993 } else if (iptr->sx.val.l == 0xffffffffL) {
996 M_LSUB(REG_ZERO, s1, d);
998 } else if (iptr->sx.val.l == 0xffffffffffL) {
999 M_ZAPNOT_IMM(s1, 0x1f, d);
1001 M_LSUB(REG_ZERO, s1, d);
1002 M_ZAPNOT_IMM(d, 0x1f, d);
1003 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1004 M_ZAPNOT_IMM(s1, 0x3f, d);
1006 M_LSUB(REG_ZERO, s1, d);
1007 M_ZAPNOT_IMM(d, 0x3f, d);
1008 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1009 M_ZAPNOT_IMM(s1, 0x7f, d);
1011 M_LSUB(REG_ZERO, s1, d);
1012 M_ZAPNOT_IMM(d, 0x7f, d);
1014 LCONST(REG_ITMP2, iptr->sx.val.l);
1015 M_AND(s1, REG_ITMP2, d);
1017 M_LSUB(REG_ZERO, s1, d);
1018 M_AND(d, REG_ITMP2, d);
1020 M_LSUB(REG_ZERO, d, d);
1021 emit_store_dst(jd, iptr, d);
1024 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1028 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1029 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1031 emit_store_dst(jd, iptr, d);
1034 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1035 /* sx.val.i = constant */
1037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1038 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1039 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1040 M_OR_IMM(s1, iptr->sx.val.i, d);
1042 ICONST(REG_ITMP2, iptr->sx.val.i);
1043 M_OR(s1, REG_ITMP2, d);
1045 emit_store_dst(jd, iptr, d);
1048 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1049 /* sx.val.l = constant */
1051 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1052 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1053 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1054 M_OR_IMM(s1, iptr->sx.val.l, d);
1056 LCONST(REG_ITMP2, iptr->sx.val.l);
1057 M_OR(s1, REG_ITMP2, d);
1059 emit_store_dst(jd, iptr, d);
1062 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1066 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1067 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1073 /* sx.val.i = constant */
1075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1077 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1078 M_XOR_IMM(s1, iptr->sx.val.i, d);
1080 ICONST(REG_ITMP2, iptr->sx.val.i);
1081 M_XOR(s1, REG_ITMP2, d);
1083 emit_store_dst(jd, iptr, d);
1086 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1087 /* sx.val.l = constant */
1089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1090 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1091 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1092 M_XOR_IMM(s1, iptr->sx.val.l, d);
1094 LCONST(REG_ITMP2, iptr->sx.val.l);
1095 M_XOR(s1, REG_ITMP2, d);
1097 emit_store_dst(jd, iptr, d);
1101 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1104 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1105 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1106 M_CMPLT(s1, s2, REG_ITMP3);
1107 M_CMPLT(s2, s1, REG_ITMP1);
1108 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1109 emit_store_dst(jd, iptr, d);
1113 /* floating operations ************************************************/
1115 case ICMD_FNEG: /* ..., value ==> ..., - value */
1117 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1118 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1120 emit_store_dst(jd, iptr, d);
1123 case ICMD_DNEG: /* ..., value ==> ..., - value */
1125 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1126 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1128 emit_store_dst(jd, iptr, d);
1131 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1133 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1134 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1135 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1139 if (d == s1 || d == s2) {
1140 M_FADDS(s1, s2, REG_FTMP3);
1142 M_FMOV(REG_FTMP3, d);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1153 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1154 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1155 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1159 if (d == s1 || d == s2) {
1160 M_DADDS(s1, s2, REG_FTMP3);
1162 M_FMOV(REG_FTMP3, d);
1168 emit_store_dst(jd, iptr, d);
1171 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1173 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1174 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1175 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1179 if (d == s1 || d == s2) {
1180 M_FSUBS(s1, s2, REG_FTMP3);
1182 M_FMOV(REG_FTMP3, d);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1193 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1194 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1195 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1199 if (d == s1 || d == s2) {
1200 M_DSUBS(s1, s2, REG_FTMP3);
1202 M_FMOV(REG_FTMP3, d);
1208 emit_store_dst(jd, iptr, d);
1211 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1213 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1214 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1215 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1219 if (d == s1 || d == s2) {
1220 M_FMULS(s1, s2, REG_FTMP3);
1222 M_FMOV(REG_FTMP3, d);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1233 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1234 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1235 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1239 if (d == s1 || d == s2) {
1240 M_DMULS(s1, s2, REG_FTMP3);
1242 M_FMOV(REG_FTMP3, d);
1248 emit_store_dst(jd, iptr, d);
1251 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1253 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1254 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1255 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1259 if (d == s1 || d == s2) {
1260 M_FDIVS(s1, s2, REG_FTMP3);
1262 M_FMOV(REG_FTMP3, d);
1268 emit_store_dst(jd, iptr, d);
1271 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1273 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1274 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1275 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1279 if (d == s1 || d == s2) {
1280 M_DDIVS(s1, s2, REG_FTMP3);
1282 M_FMOV(REG_FTMP3, d);
1288 emit_store_dst(jd, iptr, d);
1291 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1293 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1294 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1295 disp = dseg_add_unique_double(cd, 0.0);
1296 M_LST(s1, REG_PV, disp);
1297 M_DLD(d, REG_PV, disp);
1299 emit_store_dst(jd, iptr, d);
1302 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1304 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1305 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1306 disp = dseg_add_unique_double(cd, 0.0);
1307 M_LST(s1, REG_PV, disp);
1308 M_DLD(d, REG_PV, disp);
1310 emit_store_dst(jd, iptr, d);
1313 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1315 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1316 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1317 disp = dseg_add_unique_double(cd, 0.0);
1318 M_CVTDL_C(s1, REG_FTMP2);
1319 M_CVTLI(REG_FTMP2, REG_FTMP3);
1320 M_DST(REG_FTMP3, REG_PV, disp);
1321 M_ILD(d, REG_PV, disp);
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1327 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1328 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1329 disp = dseg_add_unique_double(cd, 0.0);
1330 M_CVTDL_C(s1, REG_FTMP2);
1331 M_DST(REG_FTMP2, REG_PV, disp);
1332 M_LLD(d, REG_PV, disp);
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1338 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1339 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1347 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1348 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1355 emit_store_dst(jd, iptr, d);
1358 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1360 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1361 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1362 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1364 M_LSUB_IMM(REG_ZERO, 1, d);
1365 M_FCMPEQ(s1, s2, REG_FTMP3);
1366 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1368 M_FCMPLT(s2, s1, REG_FTMP3);
1369 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1370 M_LADD_IMM(REG_ZERO, 1, d);
1372 M_LSUB_IMM(REG_ZERO, 1, d);
1373 M_FCMPEQS(s1, s2, REG_FTMP3);
1375 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1377 M_FCMPLTS(s2, s1, REG_FTMP3);
1379 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1380 M_LADD_IMM(REG_ZERO, 1, d);
1382 emit_store_dst(jd, iptr, d);
1385 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1387 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1388 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1389 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1391 M_LADD_IMM(REG_ZERO, 1, d);
1392 M_FCMPEQ(s1, s2, REG_FTMP3);
1393 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1395 M_FCMPLT(s1, s2, REG_FTMP3);
1396 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1397 M_LSUB_IMM(REG_ZERO, 1, d);
1399 M_LADD_IMM(REG_ZERO, 1, d);
1400 M_FCMPEQS(s1, s2, REG_FTMP3);
1402 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1404 M_FCMPLTS(s1, s2, REG_FTMP3);
1406 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1407 M_LSUB_IMM(REG_ZERO, 1, d);
1409 emit_store_dst(jd, iptr, d);
1413 /* memory operations **************************************************/
1415 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1417 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1418 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1419 /* implicit null-pointer check */
1420 M_ILD(d, s1, OFFSET(java_array_t, size));
1421 emit_store_dst(jd, iptr, d);
1424 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1427 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1428 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1429 /* implicit null-pointer check */
1430 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1431 if (has_ext_instr_set) {
1432 M_LADD(s2, s1, REG_ITMP1);
1433 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1437 M_LADD(s2, s1, REG_ITMP1);
1438 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1439 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0])+1);
1440 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1441 M_SRA_IMM(d, 56, d);
1443 emit_store_dst(jd, iptr, d);
1446 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1448 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1449 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1450 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1451 /* implicit null-pointer check */
1452 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1453 if (has_ext_instr_set) {
1454 M_LADD(s2, s1, REG_ITMP1);
1455 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1456 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1459 M_LADD (s2, s1, REG_ITMP1);
1460 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1461 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1462 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1463 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1465 emit_store_dst(jd, iptr, d);
1468 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1470 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1472 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1473 /* implicit null-pointer check */
1474 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1475 if (has_ext_instr_set) {
1476 M_LADD(s2, s1, REG_ITMP1);
1477 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1478 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1481 M_LADD(s2, s1, REG_ITMP1);
1482 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1483 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1484 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0])+2);
1485 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1486 M_SRA_IMM(d, 48, d);
1488 emit_store_dst(jd, iptr, d);
1491 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1494 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1495 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1496 /* implicit null-pointer check */
1497 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1498 M_S4ADDQ(s2, s1, REG_ITMP1);
1499 M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1508 /* implicit null-pointer check */
1509 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1510 M_S8ADDQ(s2, s1, REG_ITMP1);
1511 M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1512 emit_store_dst(jd, iptr, d);
1515 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1518 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1519 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1520 /* implicit null-pointer check */
1521 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1522 M_S4ADDQ(s2, s1, REG_ITMP1);
1523 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1524 emit_store_dst(jd, iptr, d);
1527 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1531 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1532 /* implicit null-pointer check */
1533 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1534 M_S8ADDQ(s2, s1, REG_ITMP1);
1535 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1536 emit_store_dst(jd, iptr, d);
1539 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1544 /* implicit null-pointer check */
1545 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1546 M_SAADDQ(s2, s1, REG_ITMP1);
1547 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1548 emit_store_dst(jd, iptr, d);
1552 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1555 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1556 /* implicit null-pointer check */
1557 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1558 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1559 if (has_ext_instr_set) {
1560 M_LADD(s2, s1, REG_ITMP1);
1561 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1564 M_LADD(s2, s1, REG_ITMP1);
1565 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1566 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1567 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1568 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1569 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1570 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1574 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1578 /* implicit null-pointer check */
1579 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1580 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1581 if (has_ext_instr_set) {
1582 M_LADD(s2, s1, REG_ITMP1);
1583 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1584 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1587 M_LADD(s2, s1, REG_ITMP1);
1588 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1589 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1590 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1591 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1592 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1593 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1594 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1598 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1601 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1602 /* implicit null-pointer check */
1603 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1604 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1605 if (has_ext_instr_set) {
1606 M_LADD(s2, s1, REG_ITMP1);
1607 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1608 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1611 M_LADD(s2, s1, REG_ITMP1);
1612 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1613 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1614 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1615 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1616 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1617 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1618 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1622 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1626 /* implicit null-pointer check */
1627 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1628 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1629 M_S4ADDQ(s2, s1, REG_ITMP1);
1630 M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1633 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1635 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1636 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1637 /* implicit null-pointer check */
1638 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1639 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1640 M_S8ADDQ(s2, s1, REG_ITMP1);
1641 M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1644 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1647 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1648 /* implicit null-pointer check */
1649 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1650 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1651 M_S4ADDQ(s2, s1, REG_ITMP1);
1652 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1655 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1659 /* implicit null-pointer check */
1660 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1661 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1662 M_S8ADDQ(s2, s1, REG_ITMP1);
1663 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1666 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1668 s1 = emit_load_s1(jd, iptr, REG_A0);
1669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1670 /* implicit null-pointer check */
1671 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1672 s3 = emit_load_s3(jd, iptr, REG_A1);
1674 M_INTMOVE(s1, REG_A0);
1675 M_INTMOVE(s3, REG_A1);
1677 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1678 M_ALD(REG_PV, REG_PV, disp);
1679 M_JSR(REG_RA, REG_PV);
1680 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1681 M_LDA(REG_PV, REG_RA, -disp);
1682 emit_arraystore_check(cd, iptr);
1684 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1686 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1687 M_SAADDQ(s2, s1, REG_ITMP1);
1688 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1692 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1694 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1695 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1696 /* implicit null-pointer check */
1697 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1698 if (has_ext_instr_set) {
1699 M_LADD(s2, s1, REG_ITMP1);
1700 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1703 M_LADD(s2, s1, REG_ITMP1);
1704 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1705 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1706 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1707 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1708 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1709 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1713 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1716 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1717 /* implicit null-pointer check */
1718 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1719 if (has_ext_instr_set) {
1720 M_LADD(s2, s1, REG_ITMP1);
1721 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1722 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1725 M_LADD(s2, s1, REG_ITMP1);
1726 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1727 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1728 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1729 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1730 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1731 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1732 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1736 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1739 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1740 /* implicit null-pointer check */
1741 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1742 if (has_ext_instr_set) {
1743 M_LADD(s2, s1, REG_ITMP1);
1744 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1745 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1748 M_LADD(s2, s1, REG_ITMP1);
1749 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1750 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1751 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1752 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1753 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1754 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1755 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1759 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1761 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1762 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1763 /* implicit null-pointer check */
1764 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1765 M_S4ADDQ(s2, s1, REG_ITMP1);
1766 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1769 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1771 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1772 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1773 /* implicit null-pointer check */
1774 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1775 M_S8ADDQ(s2, s1, REG_ITMP1);
1776 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1779 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1781 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1782 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1783 /* implicit null-pointer check */
1784 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1785 M_SAADDQ(s2, s1, REG_ITMP1);
1786 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1790 case ICMD_GETSTATIC: /* ... ==> ..., value */
1792 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1793 uf = iptr->sx.s23.s3.uf;
1794 fieldtype = uf->fieldref->parseddesc.fd->type;
1795 disp = dseg_add_unique_address(cd, uf);
1797 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1800 fi = iptr->sx.s23.s3.fmiref->p.field;
1801 fieldtype = fi->type;
1802 disp = dseg_add_address(cd, fi->value);
1804 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1805 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1809 M_ALD(REG_ITMP1, REG_PV, disp);
1810 switch (fieldtype) {
1812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1813 M_ILD(d, REG_ITMP1, 0);
1816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1817 M_LLD(d, REG_ITMP1, 0);
1820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1821 M_ALD(d, REG_ITMP1, 0);
1824 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1825 M_FLD(d, REG_ITMP1, 0);
1828 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1829 M_DLD(d, REG_ITMP1, 0);
1832 emit_store_dst(jd, iptr, d);
1835 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1837 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1838 uf = iptr->sx.s23.s3.uf;
1839 fieldtype = uf->fieldref->parseddesc.fd->type;
1840 disp = dseg_add_unique_address(cd, uf);
1842 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1845 fi = iptr->sx.s23.s3.fmiref->p.field;
1846 fieldtype = fi->type;
1847 disp = dseg_add_address(cd, fi->value);
1849 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1850 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1854 M_ALD(REG_ITMP1, REG_PV, disp);
1855 switch (fieldtype) {
1857 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1858 M_IST(s1, REG_ITMP1, 0);
1861 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1862 M_LST(s1, REG_ITMP1, 0);
1865 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1866 M_AST(s1, REG_ITMP1, 0);
1869 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1870 M_FST(s1, REG_ITMP1, 0);
1873 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1874 M_DST(s1, REG_ITMP1, 0);
1879 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1880 /* val = value (in current instruction) */
1881 /* following NOP) */
1883 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1884 uf = iptr->sx.s23.s3.uf;
1885 fieldtype = uf->fieldref->parseddesc.fd->type;
1886 disp = dseg_add_unique_address(cd, uf);
1888 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1891 fi = iptr->sx.s23.s3.fmiref->p.field;
1892 fieldtype = fi->type;
1893 disp = dseg_add_address(cd, fi->value);
1895 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1896 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1900 M_ALD(REG_ITMP1, REG_PV, disp);
1901 switch (fieldtype) {
1903 M_IST(REG_ZERO, REG_ITMP1, 0);
1906 M_LST(REG_ZERO, REG_ITMP1, 0);
1909 M_AST(REG_ZERO, REG_ITMP1, 0);
1912 M_FST(REG_ZERO, REG_ITMP1, 0);
1915 M_DST(REG_ZERO, REG_ITMP1, 0);
1921 case ICMD_GETFIELD: /* ... ==> ..., value */
1923 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1925 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1926 uf = iptr->sx.s23.s3.uf;
1927 fieldtype = uf->fieldref->parseddesc.fd->type;
1930 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1933 fi = iptr->sx.s23.s3.fmiref->p.field;
1934 fieldtype = fi->type;
1938 /* implicit null-pointer check */
1939 switch (fieldtype) {
1941 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1945 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1953 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1957 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1961 emit_store_dst(jd, iptr, d);
1964 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1968 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1969 uf = iptr->sx.s23.s3.uf;
1970 fieldtype = uf->fieldref->parseddesc.fd->type;
1975 fi = iptr->sx.s23.s3.fmiref->p.field;
1976 fieldtype = fi->type;
1980 if (IS_INT_LNG_TYPE(fieldtype))
1981 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1983 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1985 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1986 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1988 /* implicit null-pointer check */
1989 switch (fieldtype) {
1991 M_IST(s2, s1, disp);
1994 M_LST(s2, s1, disp);
1997 M_AST(s2, s1, disp);
2000 M_FST(s2, s1, disp);
2003 M_DST(s2, s1, disp);
2008 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2009 /* val = value (in current instruction) */
2010 /* following NOP) */
2012 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2014 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2015 uf = iptr->sx.s23.s3.uf;
2016 fieldtype = uf->fieldref->parseddesc.fd->type;
2019 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2022 fi = iptr->sx.s23.s3.fmiref->p.field;
2023 fieldtype = fi->type;
2027 /* implicit null-pointer check */
2028 switch (fieldtype) {
2030 M_IST(REG_ZERO, s1, disp);
2033 M_LST(REG_ZERO, s1, disp);
2036 M_AST(REG_ZERO, s1, disp);
2039 M_FST(REG_ZERO, s1, disp);
2042 M_DST(REG_ZERO, s1, disp);
2048 /* branch operations **************************************************/
2050 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053 M_INTMOVE(s1, REG_ITMP1_XPTR);
2055 #ifdef ENABLE_VERIFIER
2056 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2057 unresolved_class *uc = iptr->sx.s23.s2.uc;
2059 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2061 #endif /* ENABLE_VERIFIER */
2063 disp = dseg_add_functionptr(cd, asm_handle_exception);
2064 M_ALD(REG_ITMP2, REG_PV, disp);
2065 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2066 M_NOP; /* nop ensures that XPC is less than the end */
2067 /* of basic block */
2071 case ICMD_GOTO: /* ... ==> ... */
2072 case ICMD_RET: /* ... ==> ... */
2074 emit_br(cd, iptr->dst.block);
2078 case ICMD_JSR: /* ... ==> ... */
2080 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2084 case ICMD_IFNULL: /* ..., value ==> ... */
2085 case ICMD_IFNONNULL:
2087 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2088 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2091 case ICMD_IFEQ: /* ..., value ==> ... */
2093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094 if (iptr->sx.val.i == 0)
2095 emit_beqz(cd, iptr->dst.block, s1);
2097 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2098 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2100 ICONST(REG_ITMP2, iptr->sx.val.i);
2101 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2103 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2107 case ICMD_IFLT: /* ..., value ==> ... */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 if (iptr->sx.val.i == 0)
2111 emit_bltz(cd, iptr->dst.block, s1);
2113 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2114 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2116 ICONST(REG_ITMP2, iptr->sx.val.i);
2117 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2119 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2123 case ICMD_IFLE: /* ..., value ==> ... */
2125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2126 if (iptr->sx.val.i == 0)
2127 emit_blez(cd, iptr->dst.block, s1);
2129 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2130 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2132 ICONST(REG_ITMP2, iptr->sx.val.i);
2133 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2135 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2139 case ICMD_IFNE: /* ..., value ==> ... */
2141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2142 if (iptr->sx.val.i == 0)
2143 emit_bnez(cd, iptr->dst.block, s1);
2145 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2146 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2148 ICONST(REG_ITMP2, iptr->sx.val.i);
2149 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2151 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2155 case ICMD_IFGT: /* ..., value ==> ... */
2157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2158 if (iptr->sx.val.i == 0)
2159 emit_bgtz(cd, iptr->dst.block, s1);
2161 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2162 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2164 ICONST(REG_ITMP2, iptr->sx.val.i);
2165 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2167 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2171 case ICMD_IFGE: /* ..., value ==> ... */
2173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2174 if (iptr->sx.val.i == 0)
2175 emit_bgez(cd, iptr->dst.block, s1);
2177 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2178 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2180 ICONST(REG_ITMP2, iptr->sx.val.i);
2181 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2183 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2187 case ICMD_IF_LEQ: /* ..., value ==> ... */
2189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2190 if (iptr->sx.val.l == 0)
2191 emit_beqz(cd, iptr->dst.block, s1);
2193 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2194 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2196 LCONST(REG_ITMP2, iptr->sx.val.l);
2197 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2199 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2203 case ICMD_IF_LLT: /* ..., value ==> ... */
2205 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2206 if (iptr->sx.val.l == 0)
2207 emit_bltz(cd, iptr->dst.block, s1);
2209 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2210 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2212 LCONST(REG_ITMP2, iptr->sx.val.l);
2213 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2215 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2219 case ICMD_IF_LLE: /* ..., value ==> ... */
2221 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2222 if (iptr->sx.val.l == 0)
2223 emit_blez(cd, iptr->dst.block, s1);
2225 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2226 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2228 LCONST(REG_ITMP2, iptr->sx.val.l);
2229 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2231 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2235 case ICMD_IF_LNE: /* ..., value ==> ... */
2237 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2238 if (iptr->sx.val.l == 0)
2239 emit_bnez(cd, iptr->dst.block, s1);
2241 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2242 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2244 LCONST(REG_ITMP2, iptr->sx.val.l);
2245 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2247 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2251 case ICMD_IF_LGT: /* ..., value ==> ... */
2253 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2254 if (iptr->sx.val.l == 0)
2255 emit_bgtz(cd, iptr->dst.block, s1);
2257 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2258 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2260 LCONST(REG_ITMP2, iptr->sx.val.l);
2261 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2263 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2267 case ICMD_IF_LGE: /* ..., value ==> ... */
2269 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2270 if (iptr->sx.val.l == 0)
2271 emit_bgez(cd, iptr->dst.block, s1);
2273 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2274 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2276 LCONST(REG_ITMP2, iptr->sx.val.l);
2277 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2279 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2283 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2284 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2285 case ICMD_IF_ACMPEQ:
2287 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2288 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2289 M_CMPEQ(s1, s2, REG_ITMP1);
2290 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2293 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2294 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2295 case ICMD_IF_ACMPNE:
2297 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2298 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2299 M_CMPEQ(s1, s2, REG_ITMP1);
2300 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2303 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2304 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2307 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2308 M_CMPLT(s1, s2, REG_ITMP1);
2309 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2312 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2313 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2315 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2316 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2317 M_CMPLE(s1, s2, REG_ITMP1);
2318 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2321 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2322 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2324 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2325 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2326 M_CMPLE(s1, s2, REG_ITMP1);
2327 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2330 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2331 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2333 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2334 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2335 M_CMPLT(s1, s2, REG_ITMP1);
2336 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2340 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2343 REPLACEMENT_POINT_RETURN(cd, iptr);
2344 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2345 M_INTMOVE(s1, REG_RESULT);
2346 goto nowperformreturn;
2348 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2350 REPLACEMENT_POINT_RETURN(cd, iptr);
2351 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2352 M_INTMOVE(s1, REG_RESULT);
2354 #ifdef ENABLE_VERIFIER
2355 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2356 unresolved_class *uc = iptr->sx.s23.s2.uc;
2358 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2360 #endif /* ENABLE_VERIFIER */
2361 goto nowperformreturn;
2363 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2366 REPLACEMENT_POINT_RETURN(cd, iptr);
2367 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2368 M_FLTMOVE(s1, REG_FRESULT);
2369 goto nowperformreturn;
2371 case ICMD_RETURN: /* ... ==> ... */
2373 REPLACEMENT_POINT_RETURN(cd, iptr);
2379 p = cd->stackframesize;
2381 /* call trace function */
2383 #if !defined(NDEBUG)
2384 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2385 emit_verbosecall_exit(jd);
2388 #if defined(ENABLE_THREADS)
2389 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2390 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2392 switch (iptr->opc) {
2396 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2400 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2404 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2405 M_ALD(REG_PV, REG_PV, disp);
2406 M_JSR(REG_RA, REG_PV);
2407 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2408 M_LDA(REG_PV, REG_RA, disp);
2410 switch (iptr->opc) {
2414 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2418 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2424 /* restore return address */
2426 if (!jd->isleafmethod) {
2427 p--; M_LLD(REG_RA, REG_SP, p * 8);
2430 /* restore saved registers */
2432 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2433 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2435 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2436 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2439 /* deallocate stack */
2441 if (cd->stackframesize)
2442 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2444 M_RET(REG_ZERO, REG_RA);
2450 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2453 branch_target_t *table;
2455 table = iptr->dst.table;
2457 l = iptr->sx.s23.s2.tablelow;
2458 i = iptr->sx.s23.s3.tablehigh;
2460 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2462 M_INTMOVE(s1, REG_ITMP1);
2463 } else if (l <= 32768) {
2464 M_LDA(REG_ITMP1, s1, -l);
2466 ICONST(REG_ITMP2, l);
2467 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2470 /* number of targets */
2476 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2478 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2479 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2481 emit_beqz(cd, table[0].block, REG_ITMP2);
2483 /* build jump table top down and use address of lowest entry */
2488 dseg_add_target(cd, table->block);
2493 /* length of dataseg after last dseg_add_target is used by load */
2495 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2496 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2497 M_JMP(REG_ZERO, REG_ITMP2);
2502 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2505 lookup_target_t *lookup;
2507 lookup = iptr->dst.lookup;
2509 i = iptr->sx.s23.s2.lookupcount;
2511 MCODECHECK((i<<2)+8);
2512 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2515 val = lookup->value;
2516 if ((val >= 0) && (val <= 255)) {
2517 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2519 if ((val >= -32768) && (val <= 32767)) {
2520 M_LDA(REG_ITMP2, REG_ZERO, val);
2522 disp = dseg_add_s4(cd, val);
2523 M_ILD(REG_ITMP2, REG_PV, disp);
2525 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2527 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2531 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2537 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2539 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
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 if (bte->stub == NULL)
2605 disp = dseg_add_functionptr(cd, bte->fp);
2607 disp = dseg_add_functionptr(cd, bte->stub);
2609 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2611 /* generate the actual call */
2613 M_JSR(REG_RA, REG_PV);
2614 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2615 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2616 M_LDA(REG_PV, REG_RA, -disp);
2619 case ICMD_INVOKESPECIAL:
2620 emit_nullpointer_check(cd, iptr, REG_A0);
2623 case ICMD_INVOKESTATIC:
2625 disp = dseg_add_unique_address(cd, um);
2627 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2631 disp = dseg_add_address(cd, lm->stubroutine);
2633 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2635 /* generate the actual call */
2637 M_JSR(REG_RA, REG_PV);
2638 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2639 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2640 M_LDA(REG_PV, REG_RA, -disp);
2643 case ICMD_INVOKEVIRTUAL:
2645 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2650 s1 = OFFSET(vftbl_t, table[0]) +
2651 sizeof(methodptr) * lm->vftblindex;
2653 /* implicit null-pointer check */
2654 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2655 M_ALD(REG_PV, REG_METHODPTR, s1);
2657 /* generate the actual call */
2659 M_JSR(REG_RA, REG_PV);
2660 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2661 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2662 M_LDA(REG_PV, REG_RA, -disp);
2665 case ICMD_INVOKEINTERFACE:
2667 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2673 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2674 sizeof(methodptr*) * lm->class->index;
2676 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2679 /* implicit null-pointer check */
2680 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2681 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2682 M_ALD(REG_PV, REG_METHODPTR, s2);
2684 /* generate the actual call */
2686 M_JSR(REG_RA, REG_PV);
2687 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2688 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2689 M_LDA(REG_PV, REG_RA, -disp);
2693 /* store the return value */
2695 d = md->returntype.type;
2697 if (d != TYPE_VOID) {
2698 if (IS_INT_LNG_TYPE(d)) {
2699 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2700 M_INTMOVE(REG_RESULT, s1);
2703 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2704 M_FLTMOVE(REG_FRESULT, s1);
2706 emit_store_dst(jd, iptr, s1);
2711 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2713 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2714 /* object type cast-check */
2719 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2724 super = iptr->sx.s23.s3.c.cls;
2725 superindex = super->index;
2728 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2729 CODEGEN_CRITICAL_SECTION_NEW;
2731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2733 /* if class is not resolved, check which code to call */
2735 if (super == NULL) {
2736 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2738 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2740 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2741 iptr->sx.s23.s3.c.ref,
2744 M_ILD(REG_ITMP2, REG_PV, disp);
2745 disp = dseg_add_s4(cd, ACC_INTERFACE);
2746 M_ILD(REG_ITMP3, REG_PV, disp);
2747 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2748 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2751 /* interface checkcast code */
2753 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2754 if (super == NULL) {
2755 patcher_add_patch_ref(jd,
2756 PATCHER_checkcast_interface,
2757 iptr->sx.s23.s3.c.ref,
2761 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2763 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2764 M_ILD(REG_ITMP3, REG_ITMP2,
2765 OFFSET(vftbl_t, interfacetablelength));
2766 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2767 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2769 M_ALD(REG_ITMP3, REG_ITMP2,
2770 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2771 superindex * sizeof(methodptr*)));
2772 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2775 emit_label_br(cd, BRANCH_LABEL_4);
2777 emit_label(cd, BRANCH_LABEL_3);
2780 /* class checkcast code */
2782 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2783 if (super == NULL) {
2784 emit_label(cd, BRANCH_LABEL_2);
2786 disp = dseg_add_unique_address(cd, NULL);
2788 patcher_add_patch_ref(jd,
2789 PATCHER_resolve_classref_to_vftbl,
2790 iptr->sx.s23.s3.c.ref,
2794 disp = dseg_add_address(cd, super->vftbl);
2796 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2799 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2800 M_ALD(REG_ITMP3, REG_PV, disp);
2802 CODEGEN_CRITICAL_SECTION_START;
2804 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2805 /* if (s1 != REG_ITMP1) { */
2806 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2807 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2808 /* #if defined(ENABLE_THREADS) */
2809 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2811 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2814 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2815 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2816 M_ALD(REG_ITMP3, REG_PV, disp);
2817 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2819 CODEGEN_CRITICAL_SECTION_END;
2822 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2823 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2826 emit_label(cd, BRANCH_LABEL_5);
2829 if (super == NULL) {
2830 emit_label(cd, BRANCH_LABEL_1);
2831 emit_label(cd, BRANCH_LABEL_4);
2834 d = codegen_reg_of_dst(jd, iptr, s1);
2837 /* array type cast-check */
2839 s1 = emit_load_s1(jd, iptr, REG_A0);
2840 M_INTMOVE(s1, REG_A0);
2842 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2843 disp = dseg_add_unique_address(cd, NULL);
2845 patcher_add_patch_ref(jd,
2846 PATCHER_resolve_classref_to_classinfo,
2847 iptr->sx.s23.s3.c.ref,
2851 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2853 M_ALD(REG_A1, REG_PV, disp);
2854 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2855 M_ALD(REG_PV, REG_PV, disp);
2856 M_JSR(REG_RA, REG_PV);
2857 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2858 M_LDA(REG_PV, REG_RA, -disp);
2860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2861 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2863 d = codegen_reg_of_dst(jd, iptr, s1);
2867 emit_store_dst(jd, iptr, d);
2870 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2874 vftbl_t *supervftbl;
2877 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2883 super = iptr->sx.s23.s3.c.cls;
2884 superindex = super->index;
2885 supervftbl = super->vftbl;
2888 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2889 CODEGEN_CRITICAL_SECTION_NEW;
2891 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2895 M_MOV(s1, REG_ITMP1);
2899 /* if class is not resolved, check which code to call */
2901 if (super == NULL) {
2903 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2905 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2907 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2908 iptr->sx.s23.s3.c.ref, disp);
2910 M_ILD(REG_ITMP3, REG_PV, disp);
2912 disp = dseg_add_s4(cd, ACC_INTERFACE);
2913 M_ILD(REG_ITMP2, REG_PV, disp);
2914 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2915 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2918 /* interface instanceof code */
2920 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2921 if (super == NULL) {
2922 /* If d == REG_ITMP2, then it's destroyed in check
2927 patcher_add_patch_ref(jd,
2928 PATCHER_instanceof_interface,
2929 iptr->sx.s23.s3.c.ref, 0);
2933 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2936 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2937 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2938 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2939 M_BLEZ(REG_ITMP3, 2);
2940 M_ALD(REG_ITMP1, REG_ITMP1,
2941 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2942 superindex * sizeof(methodptr*)));
2943 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2946 emit_label_br(cd, BRANCH_LABEL_4);
2948 emit_label(cd, BRANCH_LABEL_3);
2951 /* class instanceof code */
2953 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2954 if (super == NULL) {
2955 emit_label(cd, BRANCH_LABEL_2);
2957 disp = dseg_add_unique_address(cd, NULL);
2959 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2960 iptr->sx.s23.s3.c.ref,
2964 disp = dseg_add_address(cd, supervftbl);
2967 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2970 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2971 M_ALD(REG_ITMP2, REG_PV, disp);
2973 CODEGEN_CRITICAL_SECTION_START;
2975 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2976 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2977 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2979 CODEGEN_CRITICAL_SECTION_END;
2981 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2982 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
2985 emit_label(cd, BRANCH_LABEL_5);
2988 if (super == NULL) {
2989 emit_label(cd, BRANCH_LABEL_1);
2990 emit_label(cd, BRANCH_LABEL_4);
2993 emit_store_dst(jd, iptr, d);
2997 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2999 /* check for negative sizes and copy sizes to stack if necessary */
3001 MCODECHECK((iptr->s1.argcount << 1) + 64);
3003 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3005 var = VAR(iptr->sx.s23.s2.args[s1]);
3007 /* copy SAVEDVAR sizes to stack */
3009 /* Already Preallocated? */
3011 if (!(var->flags & PREALLOC)) {
3012 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3013 M_LST(s2, REG_SP, s1 * 8);
3017 /* a0 = dimension count */
3019 ICONST(REG_A0, iptr->s1.argcount);
3021 /* is patcher function set? */
3023 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3024 disp = dseg_add_unique_address(cd, 0);
3026 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3027 iptr->sx.s23.s3.c.ref,
3031 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3033 /* a1 = arraydescriptor */
3035 M_ALD(REG_A1, REG_PV, disp);
3037 /* a2 = pointer to dimensions = stack pointer */
3039 M_INTMOVE(REG_SP, REG_A2);
3041 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3042 M_ALD(REG_PV, REG_PV, disp);
3043 M_JSR(REG_RA, REG_PV);
3044 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3045 M_LDA(REG_PV, REG_RA, -disp);
3047 /* check for exception before result assignment */
3049 emit_exception_check(cd, iptr);
3051 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3052 M_INTMOVE(REG_RESULT, d);
3053 emit_store_dst(jd, iptr, d);
3057 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3062 } /* for instruction */
3064 } /* if (bptr -> flags >= BBREACHED) */
3065 } /* for basic block */
3067 dseg_createlinenumbertable(cd);
3069 /* generate traps */
3071 emit_patcher_traps(jd);
3073 /* everything's ok */
3079 /* codegen_emit_stub_native ****************************************************
3081 Emits a stub routine which calls a native method.
3083 *******************************************************************************/
3085 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3091 s4 i, j; /* count variables */
3094 s4 funcdisp; /* displacement of the function */
3096 /* get required compiler data */
3102 /* initialize variables */
3106 /* calculate stack frame size */
3108 cd->stackframesize =
3109 1 + /* return address */
3110 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3111 sizeof(localref_table) / SIZEOF_VOID_P +
3112 1 + /* methodinfo for call trace */
3116 /* create method header */
3118 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3119 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3120 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3121 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3122 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3123 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3124 (void) dseg_addlinenumbertablesize(cd);
3125 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3127 /* generate stub code */
3129 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3130 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3132 /* get function address (this must happen before the stackframeinfo) */
3134 funcdisp = dseg_add_functionptr(cd, f);
3137 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3139 #if defined(ENABLE_GC_CACAO)
3140 /* Save callee saved integer registers in stackframeinfo (GC may
3141 need to recover them during a collection). */
3143 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3144 OFFSET(stackframeinfo, intregs);
3146 for (i = 0; i < INT_SAV_CNT; i++)
3147 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3150 /* save integer and float argument registers */
3152 for (i = 0; i < md->paramcount; i++) {
3153 if (!md->params[i].inmemory) {
3154 s1 = md->params[i].regoff;
3156 switch (md->paramtypes[i].type) {
3160 M_LST(s1, REG_SP, i * 8);
3163 M_FST(s1, REG_SP, i * 8);
3166 M_DST(s1, REG_SP, i * 8);
3172 /* prepare data structures for native function call */
3174 M_MOV(REG_SP, REG_A0);
3175 M_MOV(REG_PV, REG_A1);
3176 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3177 M_ALD(REG_PV, REG_PV, disp);
3178 M_JSR(REG_RA, REG_PV);
3179 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3180 M_LDA(REG_PV, REG_RA, -disp);
3182 /* remember class argument */
3184 if (m->flags & ACC_STATIC)
3185 M_MOV(REG_RESULT, REG_ITMP3);
3187 /* restore integer and float argument registers */
3189 for (i = 0; i < md->paramcount; i++) {
3190 if (!md->params[i].inmemory) {
3191 s1 = md->params[i].regoff;
3193 switch (md->paramtypes[i].type) {
3197 M_LLD(s1, REG_SP, i * 8);
3200 M_FLD(s1, REG_SP, i * 8);
3203 M_DLD(s1, REG_SP, i * 8);
3209 /* copy or spill arguments to new locations */
3211 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3212 t = md->paramtypes[i].type;
3214 if (IS_INT_LNG_TYPE(t)) {
3215 if (!md->params[i].inmemory) {
3216 s1 = md->params[i].regoff;
3217 s2 = nmd->params[j].regoff;
3219 if (!nmd->params[j].inmemory)
3222 M_LST(s1, REG_SP, s2);
3225 s1 = md->params[i].regoff + cd->stackframesize * 8;
3226 s2 = nmd->params[j].regoff;
3227 M_LLD(REG_ITMP1, REG_SP, s1);
3228 M_LST(REG_ITMP1, REG_SP, s2);
3232 if (!md->params[i].inmemory) {
3233 s1 = md->params[i].regoff;
3234 s2 = nmd->params[j].regoff;
3236 if (!nmd->params[j].inmemory)
3239 if (IS_2_WORD_TYPE(t))
3240 M_DST(s1, REG_SP, s2);
3242 M_FST(s1, REG_SP, s2);
3246 s1 = md->params[i].regoff + cd->stackframesize * 8;
3247 s2 = nmd->params[j].regoff;
3248 M_DLD(REG_FTMP1, REG_SP, s1);
3249 if (IS_2_WORD_TYPE(t))
3250 M_DST(REG_FTMP1, REG_SP, s2);
3252 M_FST(REG_FTMP1, REG_SP, s2);
3257 /* Handle native Java methods. */
3259 if (m->flags & ACC_NATIVE) {
3260 /* put class into second argument register */
3262 if (m->flags & ACC_STATIC)
3263 M_MOV(REG_ITMP3, REG_A1);
3265 /* put env into first argument register */
3267 disp = dseg_add_address(cd, _Jv_env);
3268 M_ALD(REG_A0, REG_PV, disp);
3271 /* do the native function call */
3273 M_ALD(REG_PV, REG_PV, funcdisp);
3274 M_JSR(REG_RA, REG_PV); /* call native method */
3275 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3276 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3278 /* save return value */
3280 switch (md->returntype.type) {
3284 M_LST(REG_RESULT, REG_SP, 0 * 8);
3287 M_FST(REG_FRESULT, REG_SP, 0 * 8);
3290 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3296 /* remove native stackframe info */
3298 M_MOV(REG_SP, REG_A0);
3299 M_MOV(REG_PV, REG_A1);
3300 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3301 M_ALD(REG_PV, REG_PV, disp);
3302 M_JSR(REG_RA, REG_PV);
3303 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3304 M_LDA(REG_PV, REG_RA, -disp);
3305 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3307 /* restore return value */
3309 switch (md->returntype.type) {
3313 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3316 M_FLD(REG_FRESULT, REG_SP, 0 * 8);
3319 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3325 #if defined(ENABLE_GC_CACAO)
3326 /* Restore callee saved integer registers from stackframeinfo (GC
3327 might have modified them during a collection). */
3329 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3330 OFFSET(stackframeinfo, intregs);
3332 for (i = 0; i < INT_SAV_CNT; i++)
3333 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3336 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3337 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3339 /* check for exception */
3341 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3342 M_RET(REG_ZERO, REG_RA); /* return to caller */
3344 /* handle exception */
3346 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3348 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3349 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3350 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3352 /* generate patcher stubs */
3354 emit_patcher_traps(jd);
3359 * These are local overrides for various environment variables in Emacs.
3360 * Please do not remove this and leave it at the end of the file, where
3361 * Emacs will automagically detect them.
3362 * ---------------------------------------------------------------------
3365 * indent-tabs-mode: t
3369 * vim:noexpandtab:sw=4:ts=4: