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 = code_is_leafmethod(code) ? 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 && code_is_synchronized(code))
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 /* IsSync contains the offset relative to the stack pointer for the
145 argument of monitor_exit used in the exception handler. Since the
146 offset could be zero and give a wrong meaning of the flag it is
149 /* XXX Remove this "offset by one". */
151 code->synchronizedoffset = (rd->memuse + 1) * 8;
153 /* REMOVEME dummy IsSync */
154 (void) dseg_add_unique_s4(cd, 0);
156 /* REMOVEME: We still need it for exception handling in assembler. */
158 if (code_is_leafmethod(code))
159 (void) dseg_add_unique_s4(cd, 1);
161 (void) dseg_add_unique_s4(cd, 0);
163 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
164 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
166 dseg_addlinenumbertablesize(cd);
168 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
170 /* create exception table */
172 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
173 dseg_add_target(cd, ex->start);
174 dseg_add_target(cd, ex->end);
175 dseg_add_target(cd, ex->handler);
176 (void) dseg_add_unique_address(cd, ex->catchtype.any);
179 /* create stack frame (if necessary) */
181 if (cd->stackframesize)
182 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
184 /* save return address and used callee saved registers */
186 p = cd->stackframesize;
187 if (!code_is_leafmethod(code)) {
188 p--; M_AST(REG_RA, REG_SP, p * 8);
190 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
191 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
193 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
194 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
197 /* take arguments out of register or stack frame */
201 for (p = 0, l = 0; p < md->paramcount; p++) {
202 t = md->paramtypes[p].type;
204 varindex = jd->local_map[l * 5 + t];
207 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
210 if (varindex == UNUSED)
215 s1 = md->params[p].regoff;
217 if (IS_INT_LNG_TYPE(t)) { /* integer args */
218 if (!md->params[p].inmemory) { /* register arguments */
219 if (!IS_INMEMORY(var->flags))
220 M_INTMOVE(s1, var->vv.regoff);
222 M_LST(s1, REG_SP, var->vv.regoff);
224 else { /* stack arguments */
225 if (!IS_INMEMORY(var->flags))
226 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
228 var->vv.regoff = cd->stackframesize * 8 + s1;
231 else { /* floating args */
232 if (!md->params[p].inmemory) { /* register arguments */
233 if (!IS_INMEMORY(var->flags))
234 M_FLTMOVE(s1, var->vv.regoff);
236 M_DST(s1, REG_SP, var->vv.regoff * 8);
238 else { /* stack arguments */
239 if (!(var->flags & INMEMORY))
240 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
242 var->vv.regoff = cd->stackframesize * 8 + s1;
247 /* call monitorenter function */
249 #if defined(ENABLE_THREADS)
250 if (checksync && code_is_synchronized(code)) {
251 /* stack offset for monitor argument */
256 if (opt_verbosecall) {
257 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
259 for (p = 0; p < INT_ARG_CNT; p++)
260 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
262 for (p = 0; p < FLT_ARG_CNT; p++)
263 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
265 s1 += INT_ARG_CNT + FLT_ARG_CNT;
267 #endif /* !defined(NDEBUG) */
269 /* decide which monitor enter function to call */
271 if (m->flags & ACC_STATIC) {
272 disp = dseg_add_address(cd, &m->class->object.header);
273 M_ALD(REG_A0, REG_PV, disp);
277 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
280 M_AST(REG_A0, REG_SP, s1 * 8);
281 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
282 M_ALD(REG_PV, REG_PV, disp);
283 M_JSR(REG_RA, REG_PV);
284 disp = (s4) (cd->mcodeptr - cd->mcodebase);
285 M_LDA(REG_PV, REG_RA, -disp);
288 if (opt_verbosecall) {
289 for (p = 0; p < INT_ARG_CNT; p++)
290 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
292 for (p = 0; p < FLT_ARG_CNT; p++)
293 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
295 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
297 #endif /* !defined(NDEBUG) */
301 /* call trace function */
304 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
305 emit_verbosecall_enter(jd);
310 /* end of header generation */
312 /* create replacement points */
314 REPLACEMENT_POINTS_INIT(cd, jd);
316 /* walk through all basic blocks */
318 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
320 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
322 if (bptr->flags >= BBREACHED) {
324 /* branch resolving */
326 codegen_resolve_branchrefs(cd, bptr);
328 /* handle replacement points */
330 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
332 /* copy interface registers to their destination */
336 #if defined(ENABLE_LSRA)
340 src = bptr->invars[len];
341 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
342 /* d = reg_of_var(m, src, REG_ITMP1); */
343 if (!(src->flags & INMEMORY))
347 M_INTMOVE(REG_ITMP1, d);
348 emit_store(jd, NULL, src, d);
355 var = VAR(bptr->invars[len]);
356 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
357 d = codegen_reg_of_var(0, var, REG_ITMP1);
358 M_INTMOVE(REG_ITMP1, d);
359 emit_store(jd, NULL, var, d);
362 assert((var->flags & INOUT));
365 #if defined(ENABLE_LSRA)
369 /* walk through all instructions */
373 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
374 if (iptr->line != currentline) {
375 dseg_addlinenumber(cd, iptr->line);
376 currentline = iptr->line;
379 MCODECHECK(64); /* an instruction usually needs < 64 words */
382 case ICMD_NOP: /* ... ==> ... */
383 case ICMD_POP: /* ..., value ==> ... */
384 case ICMD_POP2: /* ..., value, value ==> ... */
387 case ICMD_INLINE_START:
389 REPLACEMENT_POINT_INLINE_START(cd, iptr);
392 case ICMD_INLINE_BODY:
394 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
395 dseg_addlinenumber_inline_start(cd, iptr);
396 dseg_addlinenumber(cd, iptr->line);
399 case ICMD_INLINE_END:
401 dseg_addlinenumber_inline_end(cd, iptr);
402 dseg_addlinenumber(cd, iptr->line);
405 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
407 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
408 emit_nullpointer_check(cd, iptr, s1);
411 /* constant operations ************************************************/
413 case ICMD_ICONST: /* ... ==> ..., constant */
415 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
416 ICONST(d, iptr->sx.val.i);
417 emit_store_dst(jd, iptr, d);
420 case ICMD_LCONST: /* ... ==> ..., constant */
422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
423 LCONST(d, iptr->sx.val.l);
424 emit_store_dst(jd, iptr, d);
427 case ICMD_FCONST: /* ... ==> ..., constant */
429 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
430 disp = dseg_add_float(cd, iptr->sx.val.f);
431 M_FLD(d, REG_PV, disp);
432 emit_store_dst(jd, iptr, d);
435 case ICMD_DCONST: /* ... ==> ..., constant */
437 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
438 disp = dseg_add_double(cd, iptr->sx.val.d);
439 M_DLD(d, REG_PV, disp);
440 emit_store_dst(jd, iptr, d);
443 case ICMD_ACONST: /* ... ==> ..., constant */
445 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
447 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
448 constant_classref *cr = iptr->sx.val.c.ref;
450 disp = dseg_add_unique_address(cd, cr);
452 /* XXX Only add the patcher, if this position needs to
453 be patched. If there was a previous position which
454 resolved the same class, the returned displacement
455 of dseg_add_address is ok to use. */
457 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
460 M_ALD(d, REG_PV, disp);
463 if (iptr->sx.val.anyptr == NULL)
464 M_INTMOVE(REG_ZERO, d);
466 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
467 M_ALD(d, REG_PV, disp);
470 emit_store_dst(jd, iptr, d);
474 /* load/store/move/copy operations ************************************/
476 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
477 case ICMD_ALOAD: /* s1 = local variable */
481 case ICMD_ISTORE: /* ..., value ==> ... */
493 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
498 /* integer operations *************************************************/
500 case ICMD_INEG: /* ..., value ==> ..., - value */
502 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
503 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
504 M_ISUB(REG_ZERO, s1, d);
505 emit_store_dst(jd, iptr, d);
508 case ICMD_LNEG: /* ..., value ==> ..., - value */
510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
512 M_LSUB(REG_ZERO, s1, d);
513 emit_store_dst(jd, iptr, d);
516 case ICMD_I2L: /* ..., value ==> ..., value */
518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_L2I: /* ..., value ==> ..., value */
526 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
528 M_IADD(s1, REG_ZERO, d);
529 emit_store_dst(jd, iptr, d);
532 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
536 if (has_ext_instr_set) {
539 M_SLL_IMM(s1, 56, d);
540 M_SRA_IMM( d, 56, d);
542 emit_store_dst(jd, iptr, d);
545 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
550 emit_store_dst(jd, iptr, d);
553 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
557 if (has_ext_instr_set) {
560 M_SLL_IMM(s1, 48, d);
561 M_SRA_IMM( d, 48, d);
563 emit_store_dst(jd, iptr, d);
567 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
571 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573 emit_store_dst(jd, iptr, d);
577 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
578 /* sx.val.i = constant */
580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
581 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
582 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
583 M_IADD_IMM(s1, iptr->sx.val.i, d);
584 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
585 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
587 /* XXX maybe use M_LDA? */
588 ICONST(REG_ITMP2, iptr->sx.val.i);
589 M_IADD(s1, REG_ITMP2, d);
591 emit_store_dst(jd, iptr, d);
594 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
600 emit_store_dst(jd, iptr, d);
603 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
604 /* sx.val.l = constant */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
609 M_LADD_IMM(s1, iptr->sx.val.l, d);
611 LCONST(REG_ITMP2, iptr->sx.val.l);
612 M_LADD(s1, REG_ITMP2, d);
614 emit_store_dst(jd, iptr, d);
617 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
623 emit_store_dst(jd, iptr, d);
626 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
627 /* sx.val.i = constant */
629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
631 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
632 M_ISUB_IMM(s1, iptr->sx.val.i, d);
634 ICONST(REG_ITMP2, iptr->sx.val.i);
635 M_ISUB(s1, REG_ITMP2, d);
637 emit_store_dst(jd, iptr, d);
640 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
642 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
643 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
650 /* sx.val.l = constant */
652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
653 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
654 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
655 M_LSUB_IMM(s1, iptr->sx.val.l, d);
657 LCONST(REG_ITMP2, iptr->sx.val.l);
658 M_LSUB(s1, REG_ITMP2, d);
660 emit_store_dst(jd, iptr, d);
663 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
667 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
669 emit_store_dst(jd, iptr, d);
672 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
673 /* sx.val.i = constant */
675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
676 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
677 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
678 M_IMUL_IMM(s1, iptr->sx.val.i, d);
680 ICONST(REG_ITMP2, iptr->sx.val.i);
681 M_IMUL(s1, REG_ITMP2, d);
683 emit_store_dst(jd, iptr, d);
686 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
689 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
692 emit_store_dst(jd, iptr, d);
695 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
696 /* sx.val.l = constant */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
701 M_LMUL_IMM(s1, iptr->sx.val.l, d);
703 LCONST(REG_ITMP2, iptr->sx.val.l);
704 M_LMUL(s1, REG_ITMP2, d);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
710 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
712 s1 = emit_load_s1(jd, iptr, REG_A0);
713 s2 = emit_load_s2(jd, iptr, REG_A1);
714 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
715 emit_arithmetic_check(cd, iptr, s2);
717 M_INTMOVE(s1, REG_A0);
718 M_INTMOVE(s2, REG_A1);
719 bte = iptr->sx.s23.s3.bte;
720 disp = dseg_add_functionptr(cd, bte->fp);
721 M_ALD(REG_PV, REG_PV, disp);
722 M_JSR(REG_RA, REG_PV);
723 disp = (s4) (cd->mcodeptr - cd->mcodebase);
724 M_LDA(REG_PV, REG_RA, -disp);
726 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
727 emit_store_dst(jd, iptr, d);
730 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
731 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
733 s1 = emit_load_s1(jd, iptr, REG_A0);
734 s2 = emit_load_s2(jd, iptr, REG_A1);
735 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
736 emit_arithmetic_check(cd, iptr, s2);
738 M_INTMOVE(s1, REG_A0);
739 M_INTMOVE(s2, REG_A1);
740 bte = iptr->sx.s23.s3.bte;
741 disp = dseg_add_functionptr(cd, bte->fp);
742 M_ALD(REG_PV, REG_PV, disp);
743 M_JSR(REG_RA, REG_PV);
744 disp = (s4) (cd->mcodeptr - cd->mcodebase);
745 M_LDA(REG_PV, REG_RA, -disp);
747 M_INTMOVE(REG_RESULT, d);
748 emit_store_dst(jd, iptr, d);
751 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
752 case ICMD_LDIVPOW2: /* val.i = constant */
754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
756 if (iptr->sx.val.i <= 15) {
757 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
758 M_CMOVGE(s1, s1, REG_ITMP2);
760 M_SRA_IMM(s1, 63, REG_ITMP2);
761 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
762 M_LADD(s1, REG_ITMP2, REG_ITMP2);
764 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
765 emit_store_dst(jd, iptr, d);
768 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
773 M_AND_IMM(s2, 0x1f, REG_ITMP3);
774 M_SLL(s1, REG_ITMP3, d);
775 M_IADD(d, REG_ZERO, d);
776 emit_store_dst(jd, iptr, d);
779 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
780 /* sx.val.i = constant */
782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
783 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
784 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
785 M_IADD(d, REG_ZERO, d);
786 emit_store_dst(jd, iptr, d);
789 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
792 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
794 M_AND_IMM(s2, 0x1f, REG_ITMP3);
795 M_SRA(s1, REG_ITMP3, d);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
800 /* sx.val.i = constant */
802 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
804 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
811 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813 M_AND_IMM(s2, 0x1f, REG_ITMP2);
815 M_SRL(d, REG_ITMP2, d);
816 M_IADD(d, REG_ZERO, d);
817 emit_store_dst(jd, iptr, d);
820 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
821 /* sx.val.i = constant */
823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
826 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
827 M_IADD(d, REG_ZERO, d);
828 emit_store_dst(jd, iptr, d);
831 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
834 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
835 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
837 emit_store_dst(jd, iptr, d);
840 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
841 /* sx.val.i = constant */
843 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
844 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
845 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
846 emit_store_dst(jd, iptr, d);
849 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
853 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855 emit_store_dst(jd, iptr, d);
858 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
859 /* sx.val.i = constant */
861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
862 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
863 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
864 emit_store_dst(jd, iptr, d);
867 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
870 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
871 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
873 emit_store_dst(jd, iptr, d);
876 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
877 /* sx.val.i = constant */
879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
880 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
881 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
882 emit_store_dst(jd, iptr, d);
885 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
888 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
889 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
890 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
892 emit_store_dst(jd, iptr, d);
895 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
896 /* sx.val.i = constant */
898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
901 M_AND_IMM(s1, iptr->sx.val.i, d);
902 } else if (iptr->sx.val.i == 0xffff) {
904 } else if (iptr->sx.val.i == 0xffffff) {
905 M_ZAPNOT_IMM(s1, 0x07, d);
907 ICONST(REG_ITMP2, iptr->sx.val.i);
908 M_AND(s1, REG_ITMP2, d);
910 emit_store_dst(jd, iptr, d);
913 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
914 /* sx.val.i = constant */
916 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
917 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
919 M_MOV(s1, REG_ITMP1);
922 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
923 M_AND_IMM(s1, iptr->sx.val.i, d);
925 M_ISUB(REG_ZERO, s1, d);
926 M_AND_IMM(d, iptr->sx.val.i, d);
927 } else if (iptr->sx.val.i == 0xffff) {
930 M_ISUB(REG_ZERO, s1, d);
932 } else if (iptr->sx.val.i == 0xffffff) {
933 M_ZAPNOT_IMM(s1, 0x07, d);
935 M_ISUB(REG_ZERO, s1, d);
936 M_ZAPNOT_IMM(d, 0x07, d);
938 ICONST(REG_ITMP2, iptr->sx.val.i);
939 M_AND(s1, REG_ITMP2, d);
941 M_ISUB(REG_ZERO, s1, d);
942 M_AND(d, REG_ITMP2, d);
944 M_ISUB(REG_ZERO, d, d);
945 emit_store_dst(jd, iptr, d);
948 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
949 /* sx.val.l = constant */
951 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
952 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
953 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
954 M_AND_IMM(s1, iptr->sx.val.l, d);
955 } else if (iptr->sx.val.l == 0xffffL) {
957 } else if (iptr->sx.val.l == 0xffffffL) {
958 M_ZAPNOT_IMM(s1, 0x07, d);
959 } else if (iptr->sx.val.l == 0xffffffffL) {
961 } else if (iptr->sx.val.l == 0xffffffffffL) {
962 M_ZAPNOT_IMM(s1, 0x1f, d);
963 } else if (iptr->sx.val.l == 0xffffffffffffL) {
964 M_ZAPNOT_IMM(s1, 0x3f, d);
965 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
966 M_ZAPNOT_IMM(s1, 0x7f, d);
968 LCONST(REG_ITMP2, iptr->sx.val.l);
969 M_AND(s1, REG_ITMP2, d);
971 emit_store_dst(jd, iptr, d);
974 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
975 /* sx.val.l = constant */
977 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
978 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
980 M_MOV(s1, REG_ITMP1);
983 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
984 M_AND_IMM(s1, iptr->sx.val.l, d);
986 M_LSUB(REG_ZERO, s1, d);
987 M_AND_IMM(d, iptr->sx.val.l, d);
988 } else if (iptr->sx.val.l == 0xffffL) {
991 M_LSUB(REG_ZERO, s1, d);
993 } else if (iptr->sx.val.l == 0xffffffL) {
994 M_ZAPNOT_IMM(s1, 0x07, d);
996 M_LSUB(REG_ZERO, s1, d);
997 M_ZAPNOT_IMM(d, 0x07, d);
998 } else if (iptr->sx.val.l == 0xffffffffL) {
1001 M_LSUB(REG_ZERO, s1, d);
1003 } else if (iptr->sx.val.l == 0xffffffffffL) {
1004 M_ZAPNOT_IMM(s1, 0x1f, d);
1006 M_LSUB(REG_ZERO, s1, d);
1007 M_ZAPNOT_IMM(d, 0x1f, d);
1008 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1009 M_ZAPNOT_IMM(s1, 0x3f, d);
1011 M_LSUB(REG_ZERO, s1, d);
1012 M_ZAPNOT_IMM(d, 0x3f, d);
1013 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1014 M_ZAPNOT_IMM(s1, 0x7f, d);
1016 M_LSUB(REG_ZERO, s1, d);
1017 M_ZAPNOT_IMM(d, 0x7f, d);
1019 LCONST(REG_ITMP2, iptr->sx.val.l);
1020 M_AND(s1, REG_ITMP2, d);
1022 M_LSUB(REG_ZERO, s1, d);
1023 M_AND(d, REG_ITMP2, d);
1025 M_LSUB(REG_ZERO, d, d);
1026 emit_store_dst(jd, iptr, d);
1029 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1032 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1033 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1034 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1036 emit_store_dst(jd, iptr, d);
1039 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1040 /* sx.val.i = constant */
1042 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1043 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1044 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1045 M_OR_IMM(s1, iptr->sx.val.i, d);
1047 ICONST(REG_ITMP2, iptr->sx.val.i);
1048 M_OR(s1, REG_ITMP2, d);
1050 emit_store_dst(jd, iptr, d);
1053 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1054 /* sx.val.l = constant */
1056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1057 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1058 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1059 M_OR_IMM(s1, iptr->sx.val.l, d);
1061 LCONST(REG_ITMP2, iptr->sx.val.l);
1062 M_OR(s1, REG_ITMP2, d);
1064 emit_store_dst(jd, iptr, d);
1067 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1070 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1071 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1072 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1074 emit_store_dst(jd, iptr, d);
1077 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1078 /* sx.val.i = constant */
1080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1081 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1082 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1083 M_XOR_IMM(s1, iptr->sx.val.i, d);
1085 ICONST(REG_ITMP2, iptr->sx.val.i);
1086 M_XOR(s1, REG_ITMP2, d);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1092 /* sx.val.l = constant */
1094 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1095 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1096 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1097 M_XOR_IMM(s1, iptr->sx.val.l, d);
1099 LCONST(REG_ITMP2, iptr->sx.val.l);
1100 M_XOR(s1, REG_ITMP2, d);
1102 emit_store_dst(jd, iptr, d);
1106 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1109 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1110 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1111 M_CMPLT(s1, s2, REG_ITMP3);
1112 M_CMPLT(s2, s1, REG_ITMP1);
1113 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1114 emit_store_dst(jd, iptr, d);
1118 /* floating operations ************************************************/
1120 case ICMD_FNEG: /* ..., value ==> ..., - value */
1122 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1123 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1125 emit_store_dst(jd, iptr, d);
1128 case ICMD_DNEG: /* ..., value ==> ..., - value */
1130 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1131 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1138 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1139 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1140 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1144 if (d == s1 || d == s2) {
1145 M_FADDS(s1, s2, REG_FTMP3);
1147 M_FMOV(REG_FTMP3, d);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1158 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1159 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1160 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1164 if (d == s1 || d == s2) {
1165 M_DADDS(s1, s2, REG_FTMP3);
1167 M_FMOV(REG_FTMP3, d);
1173 emit_store_dst(jd, iptr, d);
1176 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1178 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1179 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1180 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1184 if (d == s1 || d == s2) {
1185 M_FSUBS(s1, s2, REG_FTMP3);
1187 M_FMOV(REG_FTMP3, d);
1193 emit_store_dst(jd, iptr, d);
1196 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1198 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1199 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1204 if (d == s1 || d == s2) {
1205 M_DSUBS(s1, s2, REG_FTMP3);
1207 M_FMOV(REG_FTMP3, d);
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1218 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1219 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1220 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1224 if (d == s1 || d == s2) {
1225 M_FMULS(s1, s2, REG_FTMP3);
1227 M_FMOV(REG_FTMP3, d);
1233 emit_store_dst(jd, iptr, d);
1236 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1238 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1239 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1240 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1244 if (d == s1 || d == s2) {
1245 M_DMULS(s1, s2, REG_FTMP3);
1247 M_FMOV(REG_FTMP3, d);
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1258 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1260 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1264 if (d == s1 || d == s2) {
1265 M_FDIVS(s1, s2, REG_FTMP3);
1267 M_FMOV(REG_FTMP3, d);
1273 emit_store_dst(jd, iptr, d);
1276 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1278 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1279 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1280 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1284 if (d == s1 || d == s2) {
1285 M_DDIVS(s1, s2, REG_FTMP3);
1287 M_FMOV(REG_FTMP3, d);
1293 emit_store_dst(jd, iptr, d);
1296 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1298 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1299 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1300 disp = dseg_add_unique_double(cd, 0.0);
1301 M_LST(s1, REG_PV, disp);
1302 M_DLD(d, REG_PV, disp);
1304 emit_store_dst(jd, iptr, d);
1307 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1310 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1311 disp = dseg_add_unique_double(cd, 0.0);
1312 M_LST(s1, REG_PV, disp);
1313 M_DLD(d, REG_PV, disp);
1315 emit_store_dst(jd, iptr, d);
1318 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1320 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1321 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1322 disp = dseg_add_unique_double(cd, 0.0);
1323 M_CVTDL_C(s1, REG_FTMP2);
1324 M_CVTLI(REG_FTMP2, REG_FTMP3);
1325 M_DST(REG_FTMP3, REG_PV, disp);
1326 M_ILD(d, REG_PV, disp);
1327 emit_store_dst(jd, iptr, d);
1330 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1332 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1333 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1334 disp = dseg_add_unique_double(cd, 0.0);
1335 M_CVTDL_C(s1, REG_FTMP2);
1336 M_DST(REG_FTMP2, REG_PV, disp);
1337 M_LLD(d, REG_PV, disp);
1338 emit_store_dst(jd, iptr, d);
1341 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1343 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1344 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1347 emit_store_dst(jd, iptr, d);
1350 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1352 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1353 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1360 emit_store_dst(jd, iptr, d);
1363 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1365 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1366 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1369 M_LSUB_IMM(REG_ZERO, 1, d);
1370 M_FCMPEQ(s1, s2, REG_FTMP3);
1371 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1373 M_FCMPLT(s2, s1, REG_FTMP3);
1374 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1375 M_LADD_IMM(REG_ZERO, 1, d);
1377 M_LSUB_IMM(REG_ZERO, 1, d);
1378 M_FCMPEQS(s1, s2, REG_FTMP3);
1380 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1382 M_FCMPLTS(s2, s1, REG_FTMP3);
1384 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1385 M_LADD_IMM(REG_ZERO, 1, d);
1387 emit_store_dst(jd, iptr, d);
1390 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1392 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1393 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1394 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1396 M_LADD_IMM(REG_ZERO, 1, d);
1397 M_FCMPEQ(s1, s2, REG_FTMP3);
1398 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1400 M_FCMPLT(s1, s2, REG_FTMP3);
1401 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1402 M_LSUB_IMM(REG_ZERO, 1, d);
1404 M_LADD_IMM(REG_ZERO, 1, d);
1405 M_FCMPEQS(s1, s2, REG_FTMP3);
1407 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1409 M_FCMPLTS(s1, s2, REG_FTMP3);
1411 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1412 M_LSUB_IMM(REG_ZERO, 1, d);
1414 emit_store_dst(jd, iptr, d);
1418 /* memory operations **************************************************/
1420 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1422 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1423 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1424 /* implicit null-pointer check */
1425 M_ILD(d, s1, OFFSET(java_array_t, size));
1426 emit_store_dst(jd, iptr, d);
1429 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1431 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1432 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1434 /* implicit null-pointer check */
1435 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1436 if (has_ext_instr_set) {
1437 M_LADD(s2, s1, REG_ITMP1);
1438 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray_t, data[0]));
1442 M_LADD(s2, s1, REG_ITMP1);
1443 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1444 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0])+1);
1445 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1446 M_SRA_IMM(d, 56, d);
1448 emit_store_dst(jd, iptr, d);
1451 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1453 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1454 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1456 /* implicit null-pointer check */
1457 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1458 if (has_ext_instr_set) {
1459 M_LADD(s2, s1, REG_ITMP1);
1460 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1461 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1464 M_LADD (s2, s1, REG_ITMP1);
1465 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1466 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1467 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1468 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1470 emit_store_dst(jd, iptr, d);
1473 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1475 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1476 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1477 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1478 /* implicit null-pointer check */
1479 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1480 if (has_ext_instr_set) {
1481 M_LADD(s2, s1, REG_ITMP1);
1482 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1483 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray_t, data[0]));
1486 M_LADD(s2, s1, REG_ITMP1);
1487 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1488 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1489 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0])+2);
1490 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1491 M_SRA_IMM(d, 48, d);
1493 emit_store_dst(jd, iptr, d);
1496 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1498 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1499 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1501 /* implicit null-pointer check */
1502 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1503 M_S4ADDQ(s2, s1, REG_ITMP1);
1504 M_ILD(d, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1505 emit_store_dst(jd, iptr, d);
1508 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1513 /* implicit null-pointer check */
1514 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1515 M_S8ADDQ(s2, s1, REG_ITMP1);
1516 M_LLD(d, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1517 emit_store_dst(jd, iptr, d);
1520 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1523 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1524 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1525 /* implicit null-pointer check */
1526 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1527 M_S4ADDQ(s2, s1, REG_ITMP1);
1528 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1529 emit_store_dst(jd, iptr, d);
1532 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1534 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1535 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1536 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1537 /* implicit null-pointer check */
1538 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1539 M_S8ADDQ(s2, s1, REG_ITMP1);
1540 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1541 emit_store_dst(jd, iptr, d);
1544 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1547 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1549 /* implicit null-pointer check */
1550 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1551 M_SAADDQ(s2, s1, REG_ITMP1);
1552 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1553 emit_store_dst(jd, iptr, d);
1557 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1561 /* implicit null-pointer check */
1562 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1563 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1564 if (has_ext_instr_set) {
1565 M_LADD(s2, s1, REG_ITMP1);
1566 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1569 M_LADD(s2, s1, REG_ITMP1);
1570 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1571 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1572 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1573 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1574 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1575 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1579 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1582 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1583 /* implicit null-pointer check */
1584 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1585 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1586 if (has_ext_instr_set) {
1587 M_LADD(s2, s1, REG_ITMP1);
1588 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1589 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1592 M_LADD(s2, s1, REG_ITMP1);
1593 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1594 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1595 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1596 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1597 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1598 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1599 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1603 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1606 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1607 /* implicit null-pointer check */
1608 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1609 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1610 if (has_ext_instr_set) {
1611 M_LADD(s2, s1, REG_ITMP1);
1612 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1613 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1616 M_LADD(s2, s1, REG_ITMP1);
1617 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1618 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1619 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1620 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1621 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1622 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1623 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1627 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1630 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1631 /* implicit null-pointer check */
1632 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1633 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1634 M_S4ADDQ(s2, s1, REG_ITMP1);
1635 M_IST(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1638 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1640 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1641 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1642 /* implicit null-pointer check */
1643 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1644 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1645 M_S8ADDQ(s2, s1, REG_ITMP1);
1646 M_LST(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1649 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1652 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1653 /* implicit null-pointer check */
1654 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1655 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1656 M_S4ADDQ(s2, s1, REG_ITMP1);
1657 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1660 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1663 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1664 /* implicit null-pointer check */
1665 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1666 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1667 M_S8ADDQ(s2, s1, REG_ITMP1);
1668 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1671 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1673 s1 = emit_load_s1(jd, iptr, REG_A0);
1674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1675 /* implicit null-pointer check */
1676 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1677 s3 = emit_load_s3(jd, iptr, REG_A1);
1679 M_INTMOVE(s1, REG_A0);
1680 M_INTMOVE(s3, REG_A1);
1682 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1683 M_ALD(REG_PV, REG_PV, disp);
1684 M_JSR(REG_RA, REG_PV);
1685 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1686 M_LDA(REG_PV, REG_RA, -disp);
1687 emit_arraystore_check(cd, iptr);
1689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1691 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1692 M_SAADDQ(s2, s1, REG_ITMP1);
1693 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1697 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1701 /* implicit null-pointer check */
1702 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1703 if (has_ext_instr_set) {
1704 M_LADD(s2, s1, REG_ITMP1);
1705 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1708 M_LADD(s2, s1, REG_ITMP1);
1709 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1710 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1711 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1712 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1713 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1714 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1718 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1722 /* implicit null-pointer check */
1723 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1724 if (has_ext_instr_set) {
1725 M_LADD(s2, s1, REG_ITMP1);
1726 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1727 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1730 M_LADD(s2, s1, REG_ITMP1);
1731 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1732 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1733 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1734 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1735 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1736 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1737 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1741 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1743 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1744 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1745 /* implicit null-pointer check */
1746 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1747 if (has_ext_instr_set) {
1748 M_LADD(s2, s1, REG_ITMP1);
1749 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1750 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1753 M_LADD(s2, s1, REG_ITMP1);
1754 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1755 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1756 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray_t, data[0]));
1757 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1758 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1759 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1760 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1764 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1768 /* implicit null-pointer check */
1769 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1770 M_S4ADDQ(s2, s1, REG_ITMP1);
1771 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1774 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1776 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1777 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1778 /* implicit null-pointer check */
1779 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1780 M_S8ADDQ(s2, s1, REG_ITMP1);
1781 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1784 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1786 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1787 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1788 /* implicit null-pointer check */
1789 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1790 M_SAADDQ(s2, s1, REG_ITMP1);
1791 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1795 case ICMD_GETSTATIC: /* ... ==> ..., value */
1797 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1798 uf = iptr->sx.s23.s3.uf;
1799 fieldtype = uf->fieldref->parseddesc.fd->type;
1800 disp = dseg_add_unique_address(cd, uf);
1802 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1805 fi = iptr->sx.s23.s3.fmiref->p.field;
1806 fieldtype = fi->type;
1807 disp = dseg_add_address(cd, fi->value);
1809 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1810 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1814 M_ALD(REG_ITMP1, REG_PV, disp);
1815 switch (fieldtype) {
1817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1818 M_ILD(d, REG_ITMP1, 0);
1821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1822 M_LLD(d, REG_ITMP1, 0);
1825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1826 M_ALD(d, REG_ITMP1, 0);
1829 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1830 M_FLD(d, REG_ITMP1, 0);
1833 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1834 M_DLD(d, REG_ITMP1, 0);
1837 emit_store_dst(jd, iptr, d);
1840 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1842 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1843 uf = iptr->sx.s23.s3.uf;
1844 fieldtype = uf->fieldref->parseddesc.fd->type;
1845 disp = dseg_add_unique_address(cd, uf);
1847 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1850 fi = iptr->sx.s23.s3.fmiref->p.field;
1851 fieldtype = fi->type;
1852 disp = dseg_add_address(cd, fi->value);
1854 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1855 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1859 M_ALD(REG_ITMP1, REG_PV, disp);
1860 switch (fieldtype) {
1862 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1863 M_IST(s1, REG_ITMP1, 0);
1866 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1867 M_LST(s1, REG_ITMP1, 0);
1870 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1871 M_AST(s1, REG_ITMP1, 0);
1874 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1875 M_FST(s1, REG_ITMP1, 0);
1878 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1879 M_DST(s1, REG_ITMP1, 0);
1884 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1885 /* val = value (in current instruction) */
1886 /* following NOP) */
1888 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1889 uf = iptr->sx.s23.s3.uf;
1890 fieldtype = uf->fieldref->parseddesc.fd->type;
1891 disp = dseg_add_unique_address(cd, uf);
1893 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1896 fi = iptr->sx.s23.s3.fmiref->p.field;
1897 fieldtype = fi->type;
1898 disp = dseg_add_address(cd, fi->value);
1900 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1901 patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->class,
1905 M_ALD(REG_ITMP1, REG_PV, disp);
1906 switch (fieldtype) {
1908 M_IST(REG_ZERO, REG_ITMP1, 0);
1911 M_LST(REG_ZERO, REG_ITMP1, 0);
1914 M_AST(REG_ZERO, REG_ITMP1, 0);
1917 M_FST(REG_ZERO, REG_ITMP1, 0);
1920 M_DST(REG_ZERO, REG_ITMP1, 0);
1926 case ICMD_GETFIELD: /* ... ==> ..., value */
1928 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1930 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1931 uf = iptr->sx.s23.s3.uf;
1932 fieldtype = uf->fieldref->parseddesc.fd->type;
1935 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1938 fi = iptr->sx.s23.s3.fmiref->p.field;
1939 fieldtype = fi->type;
1943 /* implicit null-pointer check */
1944 switch (fieldtype) {
1946 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1954 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1958 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1962 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1966 emit_store_dst(jd, iptr, d);
1969 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1973 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1974 uf = iptr->sx.s23.s3.uf;
1975 fieldtype = uf->fieldref->parseddesc.fd->type;
1980 fi = iptr->sx.s23.s3.fmiref->p.field;
1981 fieldtype = fi->type;
1985 if (IS_INT_LNG_TYPE(fieldtype))
1986 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1988 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1990 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1991 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
1993 /* implicit null-pointer check */
1994 switch (fieldtype) {
1996 M_IST(s2, s1, disp);
1999 M_LST(s2, s1, disp);
2002 M_AST(s2, s1, disp);
2005 M_FST(s2, s1, disp);
2008 M_DST(s2, s1, disp);
2013 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2014 /* val = value (in current instruction) */
2015 /* following NOP) */
2017 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2019 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2020 uf = iptr->sx.s23.s3.uf;
2021 fieldtype = uf->fieldref->parseddesc.fd->type;
2024 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2027 fi = iptr->sx.s23.s3.fmiref->p.field;
2028 fieldtype = fi->type;
2032 /* implicit null-pointer check */
2033 switch (fieldtype) {
2035 M_IST(REG_ZERO, s1, disp);
2038 M_LST(REG_ZERO, s1, disp);
2041 M_AST(REG_ZERO, s1, disp);
2044 M_FST(REG_ZERO, s1, disp);
2047 M_DST(REG_ZERO, s1, disp);
2053 /* branch operations **************************************************/
2055 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2057 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2058 M_INTMOVE(s1, REG_ITMP1_XPTR);
2060 #ifdef ENABLE_VERIFIER
2061 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2062 unresolved_class *uc = iptr->sx.s23.s2.uc;
2064 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2066 #endif /* ENABLE_VERIFIER */
2068 disp = dseg_add_functionptr(cd, asm_handle_exception);
2069 M_ALD(REG_ITMP2, REG_PV, disp);
2070 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2071 M_NOP; /* nop ensures that XPC is less than the end */
2072 /* of basic block */
2076 case ICMD_GOTO: /* ... ==> ... */
2077 case ICMD_RET: /* ... ==> ... */
2079 emit_br(cd, iptr->dst.block);
2083 case ICMD_JSR: /* ... ==> ... */
2085 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2089 case ICMD_IFNULL: /* ..., value ==> ... */
2090 case ICMD_IFNONNULL:
2092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2093 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2096 case ICMD_IFEQ: /* ..., value ==> ... */
2098 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2099 if (iptr->sx.val.i == 0)
2100 emit_beqz(cd, iptr->dst.block, s1);
2102 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2103 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2105 ICONST(REG_ITMP2, iptr->sx.val.i);
2106 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2108 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2112 case ICMD_IFLT: /* ..., value ==> ... */
2114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2115 if (iptr->sx.val.i == 0)
2116 emit_bltz(cd, iptr->dst.block, s1);
2118 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2119 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2121 ICONST(REG_ITMP2, iptr->sx.val.i);
2122 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2124 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2128 case ICMD_IFLE: /* ..., value ==> ... */
2130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131 if (iptr->sx.val.i == 0)
2132 emit_blez(cd, iptr->dst.block, s1);
2134 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2135 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2137 ICONST(REG_ITMP2, iptr->sx.val.i);
2138 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2140 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2144 case ICMD_IFNE: /* ..., value ==> ... */
2146 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2147 if (iptr->sx.val.i == 0)
2148 emit_bnez(cd, iptr->dst.block, s1);
2150 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2151 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2153 ICONST(REG_ITMP2, iptr->sx.val.i);
2154 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2156 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2160 case ICMD_IFGT: /* ..., value ==> ... */
2162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2163 if (iptr->sx.val.i == 0)
2164 emit_bgtz(cd, iptr->dst.block, s1);
2166 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2167 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2169 ICONST(REG_ITMP2, iptr->sx.val.i);
2170 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2172 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2176 case ICMD_IFGE: /* ..., value ==> ... */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 if (iptr->sx.val.i == 0)
2180 emit_bgez(cd, iptr->dst.block, s1);
2182 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2183 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2185 ICONST(REG_ITMP2, iptr->sx.val.i);
2186 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2188 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2192 case ICMD_IF_LEQ: /* ..., value ==> ... */
2194 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2195 if (iptr->sx.val.l == 0)
2196 emit_beqz(cd, iptr->dst.block, s1);
2198 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2199 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2201 LCONST(REG_ITMP2, iptr->sx.val.l);
2202 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2204 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2208 case ICMD_IF_LLT: /* ..., value ==> ... */
2210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2211 if (iptr->sx.val.l == 0)
2212 emit_bltz(cd, iptr->dst.block, s1);
2214 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2215 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2217 LCONST(REG_ITMP2, iptr->sx.val.l);
2218 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2220 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2224 case ICMD_IF_LLE: /* ..., value ==> ... */
2226 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2227 if (iptr->sx.val.l == 0)
2228 emit_blez(cd, iptr->dst.block, s1);
2230 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2231 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2233 LCONST(REG_ITMP2, iptr->sx.val.l);
2234 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2236 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2240 case ICMD_IF_LNE: /* ..., value ==> ... */
2242 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2243 if (iptr->sx.val.l == 0)
2244 emit_bnez(cd, iptr->dst.block, s1);
2246 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2247 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2249 LCONST(REG_ITMP2, iptr->sx.val.l);
2250 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2252 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2256 case ICMD_IF_LGT: /* ..., value ==> ... */
2258 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2259 if (iptr->sx.val.l == 0)
2260 emit_bgtz(cd, iptr->dst.block, s1);
2262 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2263 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2265 LCONST(REG_ITMP2, iptr->sx.val.l);
2266 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2268 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2272 case ICMD_IF_LGE: /* ..., value ==> ... */
2274 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2275 if (iptr->sx.val.l == 0)
2276 emit_bgez(cd, iptr->dst.block, s1);
2278 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2279 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2281 LCONST(REG_ITMP2, iptr->sx.val.l);
2282 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2284 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2288 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2289 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2290 case ICMD_IF_ACMPEQ:
2292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2293 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2294 M_CMPEQ(s1, s2, REG_ITMP1);
2295 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2298 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2299 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2300 case ICMD_IF_ACMPNE:
2302 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2303 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2304 M_CMPEQ(s1, s2, REG_ITMP1);
2305 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2308 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2309 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2312 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2313 M_CMPLT(s1, s2, REG_ITMP1);
2314 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2317 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2318 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2321 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2322 M_CMPLE(s1, s2, REG_ITMP1);
2323 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2326 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2327 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2330 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2331 M_CMPLE(s1, s2, REG_ITMP1);
2332 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2335 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2336 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2340 M_CMPLT(s1, s2, REG_ITMP1);
2341 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2345 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2348 REPLACEMENT_POINT_RETURN(cd, iptr);
2349 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2350 M_INTMOVE(s1, REG_RESULT);
2351 goto nowperformreturn;
2353 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2355 REPLACEMENT_POINT_RETURN(cd, iptr);
2356 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2357 M_INTMOVE(s1, REG_RESULT);
2359 #ifdef ENABLE_VERIFIER
2360 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2361 unresolved_class *uc = iptr->sx.s23.s2.uc;
2363 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2365 #endif /* ENABLE_VERIFIER */
2366 goto nowperformreturn;
2368 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2371 REPLACEMENT_POINT_RETURN(cd, iptr);
2372 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2373 M_FLTMOVE(s1, REG_FRESULT);
2374 goto nowperformreturn;
2376 case ICMD_RETURN: /* ... ==> ... */
2378 REPLACEMENT_POINT_RETURN(cd, iptr);
2384 p = cd->stackframesize;
2386 /* call trace function */
2388 #if !defined(NDEBUG)
2389 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2390 emit_verbosecall_exit(jd);
2393 #if defined(ENABLE_THREADS)
2394 if (checksync && code_is_synchronized(code)) {
2395 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2397 switch (iptr->opc) {
2401 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2405 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2409 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2410 M_ALD(REG_PV, REG_PV, disp);
2411 M_JSR(REG_RA, REG_PV);
2412 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2413 M_LDA(REG_PV, REG_RA, disp);
2415 switch (iptr->opc) {
2419 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2423 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2429 /* restore return address */
2431 if (!code_is_leafmethod(code)) {
2432 p--; M_LLD(REG_RA, REG_SP, p * 8);
2435 /* restore saved registers */
2437 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2438 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2440 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2441 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2444 /* deallocate stack */
2446 if (cd->stackframesize)
2447 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2449 M_RET(REG_ZERO, REG_RA);
2455 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2458 branch_target_t *table;
2460 table = iptr->dst.table;
2462 l = iptr->sx.s23.s2.tablelow;
2463 i = iptr->sx.s23.s3.tablehigh;
2465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2467 M_INTMOVE(s1, REG_ITMP1);
2468 } else if (l <= 32768) {
2469 M_LDA(REG_ITMP1, s1, -l);
2471 ICONST(REG_ITMP2, l);
2472 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2475 /* number of targets */
2481 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2483 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2484 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2486 emit_beqz(cd, table[0].block, REG_ITMP2);
2488 /* build jump table top down and use address of lowest entry */
2493 dseg_add_target(cd, table->block);
2498 /* length of dataseg after last dseg_add_target is used by load */
2500 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2501 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2502 M_JMP(REG_ZERO, REG_ITMP2);
2507 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2510 lookup_target_t *lookup;
2512 lookup = iptr->dst.lookup;
2514 i = iptr->sx.s23.s2.lookupcount;
2516 MCODECHECK((i<<2)+8);
2517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2520 val = lookup->value;
2521 if ((val >= 0) && (val <= 255)) {
2522 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2524 if ((val >= -32768) && (val <= 32767)) {
2525 M_LDA(REG_ITMP2, REG_ZERO, val);
2527 disp = dseg_add_s4(cd, val);
2528 M_ILD(REG_ITMP2, REG_PV, disp);
2530 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2532 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2536 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2542 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2544 REPLACEMENT_POINT_FORGC_BUILTIN(cd, iptr);
2546 bte = iptr->sx.s23.s3.bte;
2550 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2552 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2553 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2554 case ICMD_INVOKEINTERFACE:
2556 REPLACEMENT_POINT_INVOKE(cd, iptr);
2558 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2560 um = iptr->sx.s23.s3.um;
2561 md = um->methodref->parseddesc.md;
2564 lm = iptr->sx.s23.s3.fmiref->p.method;
2566 md = lm->parseddesc;
2570 s3 = md->paramcount;
2572 MCODECHECK((s3 << 1) + 64);
2574 /* copy arguments to registers or stack location */
2576 for (s3 = s3 - 1; s3 >= 0; s3--) {
2577 var = VAR(iptr->sx.s23.s2.args[s3]);
2578 d = md->params[s3].regoff;
2580 /* already preallocated (ARGVAR)? */
2582 if (var->flags & PREALLOC)
2585 if (IS_INT_LNG_TYPE(var->type)) {
2586 if (!md->params[s3].inmemory) {
2587 s1 = emit_load(jd, iptr, var, d);
2591 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2592 M_LST(s1, REG_SP, d);
2596 if (!md->params[s3].inmemory) {
2597 s1 = emit_load(jd, iptr, var, d);
2601 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2602 M_DST(s1, REG_SP, d);
2607 switch (iptr->opc) {
2609 if (bte->stub == NULL)
2610 disp = dseg_add_functionptr(cd, bte->fp);
2612 disp = dseg_add_functionptr(cd, bte->stub);
2614 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2616 /* generate the actual call */
2618 M_JSR(REG_RA, REG_PV);
2619 REPLACEMENT_POINT_FORGC_BUILTIN_RETURN(cd, iptr);
2620 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2621 M_LDA(REG_PV, REG_RA, -disp);
2624 case ICMD_INVOKESPECIAL:
2625 emit_nullpointer_check(cd, iptr, REG_A0);
2628 case ICMD_INVOKESTATIC:
2630 disp = dseg_add_unique_address(cd, um);
2632 patcher_add_patch_ref(jd, PATCHER_invokestatic_special,
2636 disp = dseg_add_address(cd, lm->stubroutine);
2638 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2640 /* generate the actual call */
2642 M_JSR(REG_RA, REG_PV);
2643 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2644 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2645 M_LDA(REG_PV, REG_RA, -disp);
2648 case ICMD_INVOKEVIRTUAL:
2650 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
2655 s1 = OFFSET(vftbl_t, table[0]) +
2656 sizeof(methodptr) * lm->vftblindex;
2658 /* implicit null-pointer check */
2659 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2660 M_ALD(REG_PV, REG_METHODPTR, s1);
2662 /* generate the actual call */
2664 M_JSR(REG_RA, REG_PV);
2665 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2666 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2667 M_LDA(REG_PV, REG_RA, -disp);
2670 case ICMD_INVOKEINTERFACE:
2672 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
2678 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2679 sizeof(methodptr*) * lm->class->index;
2681 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2684 /* implicit null-pointer check */
2685 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
2686 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2687 M_ALD(REG_PV, REG_METHODPTR, s2);
2689 /* generate the actual call */
2691 M_JSR(REG_RA, REG_PV);
2692 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2693 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2694 M_LDA(REG_PV, REG_RA, -disp);
2698 /* store the return value */
2700 d = md->returntype.type;
2702 if (d != TYPE_VOID) {
2703 if (IS_INT_LNG_TYPE(d)) {
2704 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2705 M_INTMOVE(REG_RESULT, s1);
2708 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2709 M_FLTMOVE(REG_FRESULT, s1);
2711 emit_store_dst(jd, iptr, s1);
2716 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2718 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2719 /* object type cast-check */
2724 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2729 super = iptr->sx.s23.s3.c.cls;
2730 superindex = super->index;
2733 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2734 CODEGEN_CRITICAL_SECTION_NEW;
2736 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2738 /* if class is not resolved, check which code to call */
2740 if (super == NULL) {
2741 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2743 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2745 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2746 iptr->sx.s23.s3.c.ref,
2749 M_ILD(REG_ITMP2, REG_PV, disp);
2750 disp = dseg_add_s4(cd, ACC_INTERFACE);
2751 M_ILD(REG_ITMP3, REG_PV, disp);
2752 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2753 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2756 /* interface checkcast code */
2758 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2759 if (super == NULL) {
2760 patcher_add_patch_ref(jd,
2761 PATCHER_checkcast_interface,
2762 iptr->sx.s23.s3.c.ref,
2766 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2768 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2769 M_ILD(REG_ITMP3, REG_ITMP2,
2770 OFFSET(vftbl_t, interfacetablelength));
2771 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2772 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2774 M_ALD(REG_ITMP3, REG_ITMP2,
2775 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2776 superindex * sizeof(methodptr*)));
2777 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2780 emit_label_br(cd, BRANCH_LABEL_4);
2782 emit_label(cd, BRANCH_LABEL_3);
2785 /* class checkcast code */
2787 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2788 if (super == NULL) {
2789 emit_label(cd, BRANCH_LABEL_2);
2791 disp = dseg_add_unique_address(cd, NULL);
2793 patcher_add_patch_ref(jd,
2794 PATCHER_resolve_classref_to_vftbl,
2795 iptr->sx.s23.s3.c.ref,
2799 disp = dseg_add_address(cd, super->vftbl);
2801 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2804 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
2805 M_ALD(REG_ITMP3, REG_PV, disp);
2807 CODEGEN_CRITICAL_SECTION_START;
2809 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2810 /* if (s1 != REG_ITMP1) { */
2811 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2812 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2813 /* #if defined(ENABLE_THREADS) */
2814 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2816 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2819 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2820 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2821 M_ALD(REG_ITMP3, REG_PV, disp);
2822 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2824 CODEGEN_CRITICAL_SECTION_END;
2827 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2828 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2831 emit_label(cd, BRANCH_LABEL_5);
2834 if (super == NULL) {
2835 emit_label(cd, BRANCH_LABEL_1);
2836 emit_label(cd, BRANCH_LABEL_4);
2839 d = codegen_reg_of_dst(jd, iptr, s1);
2842 /* array type cast-check */
2844 s1 = emit_load_s1(jd, iptr, REG_A0);
2845 M_INTMOVE(s1, REG_A0);
2847 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2848 disp = dseg_add_unique_address(cd, NULL);
2850 patcher_add_patch_ref(jd,
2851 PATCHER_resolve_classref_to_classinfo,
2852 iptr->sx.s23.s3.c.ref,
2856 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2858 M_ALD(REG_A1, REG_PV, disp);
2859 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2860 M_ALD(REG_PV, REG_PV, disp);
2861 M_JSR(REG_RA, REG_PV);
2862 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2863 M_LDA(REG_PV, REG_RA, -disp);
2865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2866 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2868 d = codegen_reg_of_dst(jd, iptr, s1);
2872 emit_store_dst(jd, iptr, d);
2875 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2879 vftbl_t *supervftbl;
2882 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2888 super = iptr->sx.s23.s3.c.cls;
2889 superindex = super->index;
2890 supervftbl = super->vftbl;
2893 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
2894 CODEGEN_CRITICAL_SECTION_NEW;
2896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2900 M_MOV(s1, REG_ITMP1);
2904 /* if class is not resolved, check which code to call */
2906 if (super == NULL) {
2908 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2910 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2912 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
2913 iptr->sx.s23.s3.c.ref, disp);
2915 M_ILD(REG_ITMP3, REG_PV, disp);
2917 disp = dseg_add_s4(cd, ACC_INTERFACE);
2918 M_ILD(REG_ITMP2, REG_PV, disp);
2919 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2920 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2923 /* interface instanceof code */
2925 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2926 if (super == NULL) {
2927 /* If d == REG_ITMP2, then it's destroyed in check
2932 patcher_add_patch_ref(jd,
2933 PATCHER_instanceof_interface,
2934 iptr->sx.s23.s3.c.ref, 0);
2938 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2941 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2942 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2943 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2944 M_BLEZ(REG_ITMP3, 2);
2945 M_ALD(REG_ITMP1, REG_ITMP1,
2946 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2947 superindex * sizeof(methodptr*)));
2948 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2951 emit_label_br(cd, BRANCH_LABEL_4);
2953 emit_label(cd, BRANCH_LABEL_3);
2956 /* class instanceof code */
2958 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2959 if (super == NULL) {
2960 emit_label(cd, BRANCH_LABEL_2);
2962 disp = dseg_add_unique_address(cd, NULL);
2964 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
2965 iptr->sx.s23.s3.c.ref,
2969 disp = dseg_add_address(cd, supervftbl);
2972 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2975 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
2976 M_ALD(REG_ITMP2, REG_PV, disp);
2978 CODEGEN_CRITICAL_SECTION_START;
2980 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2981 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2982 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2984 CODEGEN_CRITICAL_SECTION_END;
2986 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2987 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
2990 emit_label(cd, BRANCH_LABEL_5);
2993 if (super == NULL) {
2994 emit_label(cd, BRANCH_LABEL_1);
2995 emit_label(cd, BRANCH_LABEL_4);
2998 emit_store_dst(jd, iptr, d);
3002 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3004 /* check for negative sizes and copy sizes to stack if necessary */
3006 MCODECHECK((iptr->s1.argcount << 1) + 64);
3008 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3010 var = VAR(iptr->sx.s23.s2.args[s1]);
3012 /* copy SAVEDVAR sizes to stack */
3014 /* Already Preallocated? */
3016 if (!(var->flags & PREALLOC)) {
3017 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3018 M_LST(s2, REG_SP, s1 * 8);
3022 /* a0 = dimension count */
3024 ICONST(REG_A0, iptr->s1.argcount);
3026 /* is patcher function set? */
3028 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3029 disp = dseg_add_unique_address(cd, 0);
3031 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3032 iptr->sx.s23.s3.c.ref,
3036 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3038 /* a1 = arraydescriptor */
3040 M_ALD(REG_A1, REG_PV, disp);
3042 /* a2 = pointer to dimensions = stack pointer */
3044 M_INTMOVE(REG_SP, REG_A2);
3046 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3047 M_ALD(REG_PV, REG_PV, disp);
3048 M_JSR(REG_RA, REG_PV);
3049 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3050 M_LDA(REG_PV, REG_RA, -disp);
3052 /* check for exception before result assignment */
3054 emit_exception_check(cd, iptr);
3056 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3057 M_INTMOVE(REG_RESULT, d);
3058 emit_store_dst(jd, iptr, d);
3062 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3067 } /* for instruction */
3069 } /* if (bptr -> flags >= BBREACHED) */
3070 } /* for basic block */
3072 dseg_createlinenumbertable(cd);
3074 /* generate traps */
3076 emit_patcher_traps(jd);
3078 /* everything's ok */
3084 /* codegen_emit_stub_native ****************************************************
3086 Emits a stub routine which calls a native method.
3088 *******************************************************************************/
3090 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3096 s4 i, j; /* count variables */
3099 s4 funcdisp; /* displacement of the function */
3101 /* get required compiler data */
3107 /* initialize variables */
3111 /* calculate stack frame size */
3113 cd->stackframesize =
3114 1 + /* return address */
3115 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3116 sizeof(localref_table) / SIZEOF_VOID_P +
3117 1 + /* methodinfo for call trace */
3121 /* create method header */
3123 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3124 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3125 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3126 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3127 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3128 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3129 (void) dseg_addlinenumbertablesize(cd);
3130 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3132 /* generate stub code */
3134 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3135 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3137 /* get function address (this must happen before the stackframeinfo) */
3139 funcdisp = dseg_add_functionptr(cd, f);
3142 patcher_add_patch_ref(jd, PATCHER_resolve_native_function, m, funcdisp);
3144 #if defined(ENABLE_GC_CACAO)
3145 /* Save callee saved integer registers in stackframeinfo (GC may
3146 need to recover them during a collection). */
3148 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3149 OFFSET(stackframeinfo_t, intregs);
3151 for (i = 0; i < INT_SAV_CNT; i++)
3152 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3155 /* save integer and float argument registers */
3157 for (i = 0; i < md->paramcount; i++) {
3158 if (!md->params[i].inmemory) {
3159 s1 = md->params[i].regoff;
3161 switch (md->paramtypes[i].type) {
3165 M_LST(s1, REG_SP, i * 8);
3168 M_FST(s1, REG_SP, i * 8);
3171 M_DST(s1, REG_SP, i * 8);
3177 /* prepare data structures for native function call */
3179 M_MOV(REG_SP, REG_A0);
3180 M_MOV(REG_PV, REG_A1);
3181 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3182 M_ALD(REG_PV, REG_PV, disp);
3183 M_JSR(REG_RA, REG_PV);
3184 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3185 M_LDA(REG_PV, REG_RA, -disp);
3187 /* remember class argument */
3189 if (m->flags & ACC_STATIC)
3190 M_MOV(REG_RESULT, REG_ITMP3);
3192 /* restore integer and float argument registers */
3194 for (i = 0; i < md->paramcount; i++) {
3195 if (!md->params[i].inmemory) {
3196 s1 = md->params[i].regoff;
3198 switch (md->paramtypes[i].type) {
3202 M_LLD(s1, REG_SP, i * 8);
3205 M_FLD(s1, REG_SP, i * 8);
3208 M_DLD(s1, REG_SP, i * 8);
3214 /* copy or spill arguments to new locations */
3216 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3217 t = md->paramtypes[i].type;
3219 if (IS_INT_LNG_TYPE(t)) {
3220 if (!md->params[i].inmemory) {
3221 s1 = md->params[i].regoff;
3222 s2 = nmd->params[j].regoff;
3224 if (!nmd->params[j].inmemory)
3227 M_LST(s1, REG_SP, s2);
3230 s1 = md->params[i].regoff + cd->stackframesize * 8;
3231 s2 = nmd->params[j].regoff;
3232 M_LLD(REG_ITMP1, REG_SP, s1);
3233 M_LST(REG_ITMP1, REG_SP, s2);
3237 if (!md->params[i].inmemory) {
3238 s1 = md->params[i].regoff;
3239 s2 = nmd->params[j].regoff;
3241 if (!nmd->params[j].inmemory)
3244 if (IS_2_WORD_TYPE(t))
3245 M_DST(s1, REG_SP, s2);
3247 M_FST(s1, REG_SP, s2);
3251 s1 = md->params[i].regoff + cd->stackframesize * 8;
3252 s2 = nmd->params[j].regoff;
3253 M_DLD(REG_FTMP1, REG_SP, s1);
3254 if (IS_2_WORD_TYPE(t))
3255 M_DST(REG_FTMP1, REG_SP, s2);
3257 M_FST(REG_FTMP1, REG_SP, s2);
3262 /* Handle native Java methods. */
3264 if (m->flags & ACC_NATIVE) {
3265 /* put class into second argument register */
3267 if (m->flags & ACC_STATIC)
3268 M_MOV(REG_ITMP3, REG_A1);
3270 /* put env into first argument register */
3272 disp = dseg_add_address(cd, _Jv_env);
3273 M_ALD(REG_A0, REG_PV, disp);
3276 /* do the native function call */
3278 M_ALD(REG_PV, REG_PV, funcdisp);
3279 M_JSR(REG_RA, REG_PV); /* call native method */
3280 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3281 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3283 /* save return value */
3285 switch (md->returntype.type) {
3289 M_LST(REG_RESULT, REG_SP, 0 * 8);
3292 M_FST(REG_FRESULT, REG_SP, 0 * 8);
3295 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3301 /* remove native stackframe info */
3303 M_MOV(REG_SP, REG_A0);
3304 M_MOV(REG_PV, REG_A1);
3305 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3306 M_ALD(REG_PV, REG_PV, disp);
3307 M_JSR(REG_RA, REG_PV);
3308 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3309 M_LDA(REG_PV, REG_RA, -disp);
3310 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3312 /* restore return value */
3314 switch (md->returntype.type) {
3318 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3321 M_FLD(REG_FRESULT, REG_SP, 0 * 8);
3324 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3330 #if defined(ENABLE_GC_CACAO)
3331 /* Restore callee saved integer registers from stackframeinfo (GC
3332 might have modified them during a collection). */
3334 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo_t) +
3335 OFFSET(stackframeinfo_t, intregs);
3337 for (i = 0; i < INT_SAV_CNT; i++)
3338 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 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: