1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 7766 2007-04-19 13:24:48Z michi $
40 #include "vm/jit/alpha/arch.h"
41 #include "vm/jit/alpha/codegen.h"
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
48 #if defined(ENABLE_THREADS)
49 # include "threads/native/lock.h"
52 #include "vm/builtin.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
57 #include "vm/jit/abi.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/codegen-common.h"
60 #include "vm/jit/dseg.h"
61 #include "vm/jit/emit-common.h"
62 #include "vm/jit/jit.h"
63 #include "vm/jit/parse.h"
64 #include "vm/jit/patcher.h"
65 #include "vm/jit/reg.h"
66 #include "vm/jit/replace.h"
67 #include "vm/jit/stacktrace.h"
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
73 #include "vmcore/loader.h"
74 #include "vmcore/options.h"
77 /* codegen_emit ****************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen_emit(jitdata *jd)
89 s4 len, s1, s2, s3, d, disp;
95 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
96 unresolved_method *um;
97 builtintable_entry *bte;
100 unresolved_field *uf;
104 /* get required compiler data */
111 /* prevent compiler warnings */
124 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
126 /* space to save used callee saved registers */
128 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
129 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
131 cd->stackframesize = rd->memuse + savedregs_num;
133 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
134 if (checksync && (m->flags & ACC_SYNCHRONIZED))
135 cd->stackframesize++;
138 /* create method header */
141 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
144 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
145 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
147 #if defined(ENABLE_THREADS)
148 /* IsSync contains the offset relative to the stack pointer for the
149 argument of monitor_exit used in the exception handler. Since the
150 offset could be zero and give a wrong meaning of the flag it is
154 if (checksync && (m->flags & ACC_SYNCHRONIZED))
155 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
158 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
160 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
161 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
162 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
164 dseg_addlinenumbertablesize(cd);
166 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
168 /* create exception table */
170 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
171 dseg_add_target(cd, ex->start);
172 dseg_add_target(cd, ex->end);
173 dseg_add_target(cd, ex->handler);
174 (void) dseg_add_unique_address(cd, ex->catchtype.any);
177 /* create stack frame (if necessary) */
179 if (cd->stackframesize)
180 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
182 /* save return address and used callee saved registers */
184 p = cd->stackframesize;
185 if (!jd->isleafmethod) {
186 p--; M_AST(REG_RA, REG_SP, p * 8);
188 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
189 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
191 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
192 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
195 /* take arguments out of register or stack frame */
199 for (p = 0, l = 0; p < md->paramcount; p++) {
200 t = md->paramtypes[p].type;
202 varindex = jd->local_map[l * 5 + t];
205 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
208 if (varindex == UNUSED)
213 s1 = md->params[p].regoff;
215 if (IS_INT_LNG_TYPE(t)) { /* integer args */
216 if (!md->params[p].inmemory) { /* register arguments */
217 if (!IS_INMEMORY(var->flags))
218 M_INTMOVE(s1, var->vv.regoff);
220 M_LST(s1, REG_SP, var->vv.regoff * 8);
222 else { /* stack arguments */
223 if (!IS_INMEMORY(var->flags))
224 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) *8);
226 var->vv.regoff = cd->stackframesize + s1;
229 else { /* floating args */
230 if (!md->params[p].inmemory) { /* register arguments */
231 if (!IS_INMEMORY(var->flags))
232 M_FLTMOVE(s1, var->vv.regoff);
234 M_DST(s1, REG_SP, var->vv.regoff * 8);
236 else { /* stack arguments */
237 if (!(var->flags & INMEMORY))
238 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
240 var->vv.regoff = cd->stackframesize + s1;
245 /* call monitorenter function */
247 #if defined(ENABLE_THREADS)
248 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
249 /* stack offset for monitor argument */
254 if (opt_verbosecall) {
255 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
257 for (p = 0; p < INT_ARG_CNT; p++)
258 M_LST(abi_registers_integer_argument[p], REG_SP, p * 8);
260 for (p = 0; p < FLT_ARG_CNT; p++)
261 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
263 s1 += INT_ARG_CNT + FLT_ARG_CNT;
265 #endif /* !defined(NDEBUG) */
267 /* decide which monitor enter function to call */
269 if (m->flags & ACC_STATIC) {
270 disp = dseg_add_address(cd, &m->class->object.header);
271 M_ALD(REG_A0, REG_PV, disp);
275 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
278 M_AST(REG_A0, REG_SP, s1 * 8);
279 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
280 M_ALD(REG_PV, REG_PV, disp);
281 M_JSR(REG_RA, REG_PV);
282 disp = (s4) (cd->mcodeptr - cd->mcodebase);
283 M_LDA(REG_PV, REG_RA, -disp);
286 if (opt_verbosecall) {
287 for (p = 0; p < INT_ARG_CNT; p++)
288 M_LLD(abi_registers_integer_argument[p], REG_SP, p * 8);
290 for (p = 0; p < FLT_ARG_CNT; p++)
291 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
293 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
295 #endif /* !defined(NDEBUG) */
299 /* call trace function */
302 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
303 emit_verbosecall_enter(jd);
308 /* end of header generation */
310 /* create replacement points */
312 REPLACEMENT_POINTS_INIT(cd, jd);
314 /* walk through all basic blocks */
316 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
318 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
320 if (bptr->flags >= BBREACHED) {
322 /* branch resolving */
324 codegen_resolve_branchrefs(cd, bptr);
326 /* handle replacement points */
328 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
330 /* copy interface registers to their destination */
334 #if defined(ENABLE_LSRA)
338 src = bptr->invars[len];
339 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
340 /* d = reg_of_var(m, src, REG_ITMP1); */
341 if (!(src->flags & INMEMORY))
345 M_INTMOVE(REG_ITMP1, d);
346 emit_store(jd, NULL, src, d);
353 var = VAR(bptr->invars[len]);
354 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
355 d = codegen_reg_of_var(0, var, REG_ITMP1);
356 M_INTMOVE(REG_ITMP1, d);
357 emit_store(jd, NULL, var, d);
360 assert((var->flags & INOUT));
363 #if defined(ENABLE_LSRA)
367 /* walk through all instructions */
371 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
372 if (iptr->line != currentline) {
373 dseg_addlinenumber(cd, iptr->line);
374 currentline = iptr->line;
377 MCODECHECK(64); /* an instruction usually needs < 64 words */
380 case ICMD_NOP: /* ... ==> ... */
381 case ICMD_POP: /* ..., value ==> ... */
382 case ICMD_POP2: /* ..., value, value ==> ... */
385 case ICMD_INLINE_START:
387 REPLACEMENT_POINT_INLINE_START(cd, iptr);
390 case ICMD_INLINE_BODY:
392 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
393 dseg_addlinenumber_inline_start(cd, iptr);
394 dseg_addlinenumber(cd, iptr->line);
397 case ICMD_INLINE_END:
399 dseg_addlinenumber_inline_end(cd, iptr);
400 dseg_addlinenumber(cd, iptr->line);
403 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
405 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
406 emit_nullpointer_check(cd, iptr, s1);
409 /* constant operations ************************************************/
411 case ICMD_ICONST: /* ... ==> ..., constant */
413 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
414 ICONST(d, iptr->sx.val.i);
415 emit_store_dst(jd, iptr, d);
418 case ICMD_LCONST: /* ... ==> ..., constant */
420 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
421 LCONST(d, iptr->sx.val.l);
422 emit_store_dst(jd, iptr, d);
425 case ICMD_FCONST: /* ... ==> ..., constant */
427 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
428 disp = dseg_add_float(cd, iptr->sx.val.f);
429 M_FLD(d, REG_PV, disp);
430 emit_store_dst(jd, iptr, d);
433 case ICMD_DCONST: /* ... ==> ..., constant */
435 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
436 disp = dseg_add_double(cd, iptr->sx.val.d);
437 M_DLD(d, REG_PV, disp);
438 emit_store_dst(jd, iptr, d);
441 case ICMD_ACONST: /* ... ==> ..., constant */
443 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
445 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
446 constant_classref *cr = iptr->sx.val.c.ref;
448 disp = dseg_add_unique_address(cd, cr);
450 /* XXX Only add the patcher, if this position needs to
451 be patched. If there was a previous position which
452 resolved the same class, the returned displacement
453 of dseg_add_address is ok to use. */
455 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
458 M_ALD(d, REG_PV, disp);
461 if (iptr->sx.val.anyptr == NULL)
462 M_INTMOVE(REG_ZERO, d);
464 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
465 M_ALD(d, REG_PV, disp);
468 emit_store_dst(jd, iptr, d);
472 /* load/store/move/copy operations ************************************/
474 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
475 case ICMD_ALOAD: /* s1 = local variable */
479 case ICMD_ISTORE: /* ..., value ==> ... */
491 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
496 /* integer operations *************************************************/
498 case ICMD_INEG: /* ..., value ==> ..., - value */
500 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
502 M_ISUB(REG_ZERO, s1, d);
503 emit_store_dst(jd, iptr, d);
506 case ICMD_LNEG: /* ..., value ==> ..., - value */
508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
510 M_LSUB(REG_ZERO, s1, d);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_I2L: /* ..., value ==> ..., value */
516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_L2I: /* ..., value ==> ..., value */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
526 M_IADD(s1, REG_ZERO, d);
527 emit_store_dst(jd, iptr, d);
530 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
534 if (has_ext_instr_set) {
537 M_SLL_IMM(s1, 56, d);
538 M_SRA_IMM( d, 56, d);
540 emit_store_dst(jd, iptr, d);
543 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
548 emit_store_dst(jd, iptr, d);
551 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
554 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
555 if (has_ext_instr_set) {
558 M_SLL_IMM(s1, 48, d);
559 M_SRA_IMM( d, 48, d);
561 emit_store_dst(jd, iptr, d);
565 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
569 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
571 emit_store_dst(jd, iptr, d);
575 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
576 /* sx.val.i = constant */
578 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
579 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
580 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
581 M_IADD_IMM(s1, iptr->sx.val.i, d);
582 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
583 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
585 /* XXX maybe use M_LDA? */
586 ICONST(REG_ITMP2, iptr->sx.val.i);
587 M_IADD(s1, REG_ITMP2, d);
589 emit_store_dst(jd, iptr, d);
592 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
594 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
595 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
602 /* sx.val.l = constant */
604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
606 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
607 M_LADD_IMM(s1, iptr->sx.val.l, d);
609 LCONST(REG_ITMP2, iptr->sx.val.l);
610 M_LADD(s1, REG_ITMP2, d);
612 emit_store_dst(jd, iptr, d);
615 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
618 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
621 emit_store_dst(jd, iptr, d);
624 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
625 /* sx.val.i = constant */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
629 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
630 M_ISUB_IMM(s1, iptr->sx.val.i, d);
632 ICONST(REG_ITMP2, iptr->sx.val.i);
633 M_ISUB(s1, REG_ITMP2, d);
635 emit_store_dst(jd, iptr, d);
638 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
640 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
641 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644 emit_store_dst(jd, iptr, d);
647 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
648 /* sx.val.l = constant */
650 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
652 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
653 M_LSUB_IMM(s1, iptr->sx.val.l, d);
655 LCONST(REG_ITMP2, iptr->sx.val.l);
656 M_LSUB(s1, REG_ITMP2, d);
658 emit_store_dst(jd, iptr, d);
661 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
664 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
667 emit_store_dst(jd, iptr, d);
670 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
671 /* sx.val.i = constant */
673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
675 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
676 M_IMUL_IMM(s1, iptr->sx.val.i, d);
678 ICONST(REG_ITMP2, iptr->sx.val.i);
679 M_IMUL(s1, REG_ITMP2, d);
681 emit_store_dst(jd, iptr, d);
684 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
690 emit_store_dst(jd, iptr, d);
693 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
694 /* sx.val.l = constant */
696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
698 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
699 M_LMUL_IMM(s1, iptr->sx.val.l, d);
701 LCONST(REG_ITMP2, iptr->sx.val.l);
702 M_LMUL(s1, REG_ITMP2, d);
704 emit_store_dst(jd, iptr, d);
707 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
708 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
710 s1 = emit_load_s1(jd, iptr, REG_A0);
711 s2 = emit_load_s2(jd, iptr, REG_A1);
712 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
713 emit_arithmetic_check(cd, iptr, s2);
715 M_INTMOVE(s1, REG_A0);
716 M_INTMOVE(s2, REG_A1);
717 bte = iptr->sx.s23.s3.bte;
718 disp = dseg_add_functionptr(cd, bte->fp);
719 M_ALD(REG_PV, REG_PV, disp);
720 M_JSR(REG_RA, REG_PV);
721 disp = (s4) (cd->mcodeptr - cd->mcodebase);
722 M_LDA(REG_PV, REG_RA, -disp);
724 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
725 emit_store_dst(jd, iptr, d);
728 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
729 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
731 s1 = emit_load_s1(jd, iptr, REG_A0);
732 s2 = emit_load_s2(jd, iptr, REG_A1);
733 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
734 emit_arithmetic_check(cd, iptr, s2);
736 M_INTMOVE(s1, REG_A0);
737 M_INTMOVE(s2, REG_A1);
738 bte = iptr->sx.s23.s3.bte;
739 disp = dseg_add_functionptr(cd, bte->fp);
740 M_ALD(REG_PV, REG_PV, disp);
741 M_JSR(REG_RA, REG_PV);
742 disp = (s4) (cd->mcodeptr - cd->mcodebase);
743 M_LDA(REG_PV, REG_RA, -disp);
745 M_INTMOVE(REG_RESULT, d);
746 emit_store_dst(jd, iptr, d);
749 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
750 case ICMD_LDIVPOW2: /* val.i = constant */
752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
754 if (iptr->sx.val.i <= 15) {
755 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
756 M_CMOVGE(s1, s1, REG_ITMP2);
758 M_SRA_IMM(s1, 63, REG_ITMP2);
759 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
760 M_LADD(s1, REG_ITMP2, REG_ITMP2);
762 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
763 emit_store_dst(jd, iptr, d);
766 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
771 M_AND_IMM(s2, 0x1f, REG_ITMP3);
772 M_SLL(s1, REG_ITMP3, d);
773 M_IADD(d, REG_ZERO, d);
774 emit_store_dst(jd, iptr, d);
777 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
778 /* sx.val.i = constant */
780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
782 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
783 M_IADD(d, REG_ZERO, d);
784 emit_store_dst(jd, iptr, d);
787 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
791 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
792 M_AND_IMM(s2, 0x1f, REG_ITMP3);
793 M_SRA(s1, REG_ITMP3, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
798 /* sx.val.i = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
803 emit_store_dst(jd, iptr, d);
806 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
809 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
810 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
811 M_AND_IMM(s2, 0x1f, REG_ITMP2);
813 M_SRL(d, REG_ITMP2, d);
814 M_IADD(d, REG_ZERO, d);
815 emit_store_dst(jd, iptr, d);
818 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
819 /* sx.val.i = constant */
821 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
824 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
825 M_IADD(d, REG_ZERO, d);
826 emit_store_dst(jd, iptr, d);
829 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
832 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
839 /* sx.val.i = constant */
841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
844 emit_store_dst(jd, iptr, d);
847 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
851 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853 emit_store_dst(jd, iptr, d);
856 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
857 /* sx.val.i = constant */
859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
860 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
861 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
862 emit_store_dst(jd, iptr, d);
865 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
867 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
869 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
875 /* sx.val.i = constant */
877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
886 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
887 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
888 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
894 /* sx.val.i = constant */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
899 M_AND_IMM(s1, iptr->sx.val.i, d);
900 } else if (iptr->sx.val.i == 0xffff) {
902 } else if (iptr->sx.val.i == 0xffffff) {
903 M_ZAPNOT_IMM(s1, 0x07, d);
905 ICONST(REG_ITMP2, iptr->sx.val.i);
906 M_AND(s1, REG_ITMP2, d);
908 emit_store_dst(jd, iptr, d);
911 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
912 /* sx.val.i = constant */
914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
915 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
917 M_MOV(s1, REG_ITMP1);
920 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
921 M_AND_IMM(s1, iptr->sx.val.i, d);
923 M_ISUB(REG_ZERO, s1, d);
924 M_AND_IMM(d, iptr->sx.val.i, d);
925 } else if (iptr->sx.val.i == 0xffff) {
928 M_ISUB(REG_ZERO, s1, d);
930 } else if (iptr->sx.val.i == 0xffffff) {
931 M_ZAPNOT_IMM(s1, 0x07, d);
933 M_ISUB(REG_ZERO, s1, d);
934 M_ZAPNOT_IMM(d, 0x07, d);
936 ICONST(REG_ITMP2, iptr->sx.val.i);
937 M_AND(s1, REG_ITMP2, d);
939 M_ISUB(REG_ZERO, s1, d);
940 M_AND(d, REG_ITMP2, d);
942 M_ISUB(REG_ZERO, d, d);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
947 /* sx.val.l = constant */
949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
952 M_AND_IMM(s1, iptr->sx.val.l, d);
953 } else if (iptr->sx.val.l == 0xffffL) {
955 } else if (iptr->sx.val.l == 0xffffffL) {
956 M_ZAPNOT_IMM(s1, 0x07, d);
957 } else if (iptr->sx.val.l == 0xffffffffL) {
959 } else if (iptr->sx.val.l == 0xffffffffffL) {
960 M_ZAPNOT_IMM(s1, 0x1f, d);
961 } else if (iptr->sx.val.l == 0xffffffffffffL) {
962 M_ZAPNOT_IMM(s1, 0x3f, d);
963 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
964 M_ZAPNOT_IMM(s1, 0x7f, d);
966 LCONST(REG_ITMP2, iptr->sx.val.l);
967 M_AND(s1, REG_ITMP2, d);
969 emit_store_dst(jd, iptr, d);
972 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
973 /* sx.val.l = constant */
975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
976 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
978 M_MOV(s1, REG_ITMP1);
981 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
982 M_AND_IMM(s1, iptr->sx.val.l, d);
984 M_LSUB(REG_ZERO, s1, d);
985 M_AND_IMM(d, iptr->sx.val.l, d);
986 } else if (iptr->sx.val.l == 0xffffL) {
989 M_LSUB(REG_ZERO, s1, d);
991 } else if (iptr->sx.val.l == 0xffffffL) {
992 M_ZAPNOT_IMM(s1, 0x07, d);
994 M_LSUB(REG_ZERO, s1, d);
995 M_ZAPNOT_IMM(d, 0x07, d);
996 } else if (iptr->sx.val.l == 0xffffffffL) {
999 M_LSUB(REG_ZERO, s1, d);
1001 } else if (iptr->sx.val.l == 0xffffffffffL) {
1002 M_ZAPNOT_IMM(s1, 0x1f, d);
1004 M_LSUB(REG_ZERO, s1, d);
1005 M_ZAPNOT_IMM(d, 0x1f, d);
1006 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1007 M_ZAPNOT_IMM(s1, 0x3f, d);
1009 M_LSUB(REG_ZERO, s1, d);
1010 M_ZAPNOT_IMM(d, 0x3f, d);
1011 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1012 M_ZAPNOT_IMM(s1, 0x7f, d);
1014 M_LSUB(REG_ZERO, s1, d);
1015 M_ZAPNOT_IMM(d, 0x7f, d);
1017 LCONST(REG_ITMP2, iptr->sx.val.l);
1018 M_AND(s1, REG_ITMP2, d);
1020 M_LSUB(REG_ZERO, s1, d);
1021 M_AND(d, REG_ITMP2, d);
1023 M_LSUB(REG_ZERO, d, d);
1024 emit_store_dst(jd, iptr, d);
1027 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1030 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1031 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1032 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1034 emit_store_dst(jd, iptr, d);
1037 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1038 /* sx.val.i = constant */
1040 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1041 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1043 M_OR_IMM(s1, iptr->sx.val.i, d);
1045 ICONST(REG_ITMP2, iptr->sx.val.i);
1046 M_OR(s1, REG_ITMP2, d);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1052 /* sx.val.l = constant */
1054 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1056 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1057 M_OR_IMM(s1, iptr->sx.val.l, d);
1059 LCONST(REG_ITMP2, iptr->sx.val.l);
1060 M_OR(s1, REG_ITMP2, d);
1062 emit_store_dst(jd, iptr, d);
1065 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1068 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1069 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1070 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1076 /* sx.val.i = constant */
1078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1080 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1081 M_XOR_IMM(s1, iptr->sx.val.i, d);
1083 ICONST(REG_ITMP2, iptr->sx.val.i);
1084 M_XOR(s1, REG_ITMP2, d);
1086 emit_store_dst(jd, iptr, d);
1089 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1090 /* sx.val.l = constant */
1092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1094 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1095 M_XOR_IMM(s1, iptr->sx.val.l, d);
1097 LCONST(REG_ITMP2, iptr->sx.val.l);
1098 M_XOR(s1, REG_ITMP2, d);
1100 emit_store_dst(jd, iptr, d);
1104 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1106 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1107 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1108 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1109 M_CMPLT(s1, s2, REG_ITMP3);
1110 M_CMPLT(s2, s1, REG_ITMP1);
1111 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1112 emit_store_dst(jd, iptr, d);
1116 /* floating operations ************************************************/
1118 case ICMD_FNEG: /* ..., value ==> ..., - value */
1120 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1121 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1123 emit_store_dst(jd, iptr, d);
1126 case ICMD_DNEG: /* ..., value ==> ..., - value */
1128 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1129 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1131 emit_store_dst(jd, iptr, d);
1134 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1136 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1137 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1142 if (d == s1 || d == s2) {
1143 M_FADDS(s1, s2, REG_FTMP3);
1145 M_FMOV(REG_FTMP3, d);
1151 emit_store_dst(jd, iptr, d);
1154 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1156 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1157 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1158 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1162 if (d == s1 || d == s2) {
1163 M_DADDS(s1, s2, REG_FTMP3);
1165 M_FMOV(REG_FTMP3, d);
1171 emit_store_dst(jd, iptr, d);
1174 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1176 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1177 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1178 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1182 if (d == s1 || d == s2) {
1183 M_FSUBS(s1, s2, REG_FTMP3);
1185 M_FMOV(REG_FTMP3, d);
1191 emit_store_dst(jd, iptr, d);
1194 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1196 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1197 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1198 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1202 if (d == s1 || d == s2) {
1203 M_DSUBS(s1, s2, REG_FTMP3);
1205 M_FMOV(REG_FTMP3, d);
1211 emit_store_dst(jd, iptr, d);
1214 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1216 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1217 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1218 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1222 if (d == s1 || d == s2) {
1223 M_FMULS(s1, s2, REG_FTMP3);
1225 M_FMOV(REG_FTMP3, d);
1231 emit_store_dst(jd, iptr, d);
1234 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1236 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1237 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1238 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1242 if (d == s1 || d == s2) {
1243 M_DMULS(s1, s2, REG_FTMP3);
1245 M_FMOV(REG_FTMP3, d);
1251 emit_store_dst(jd, iptr, d);
1254 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1256 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1257 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1258 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1262 if (d == s1 || d == s2) {
1263 M_FDIVS(s1, s2, REG_FTMP3);
1265 M_FMOV(REG_FTMP3, d);
1271 emit_store_dst(jd, iptr, d);
1274 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1276 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1277 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1278 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1282 if (d == s1 || d == s2) {
1283 M_DDIVS(s1, s2, REG_FTMP3);
1285 M_FMOV(REG_FTMP3, d);
1291 emit_store_dst(jd, iptr, d);
1294 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1296 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1297 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1298 disp = dseg_add_unique_double(cd, 0.0);
1299 M_LST(s1, REG_PV, disp);
1300 M_DLD(d, REG_PV, disp);
1302 emit_store_dst(jd, iptr, d);
1305 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1308 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1309 disp = dseg_add_unique_double(cd, 0.0);
1310 M_LST(s1, REG_PV, disp);
1311 M_DLD(d, REG_PV, disp);
1313 emit_store_dst(jd, iptr, d);
1316 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1318 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1319 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1320 disp = dseg_add_unique_double(cd, 0.0);
1321 M_CVTDL_C(s1, REG_FTMP2);
1322 M_CVTLI(REG_FTMP2, REG_FTMP3);
1323 M_DST(REG_FTMP3, REG_PV, disp);
1324 M_ILD(d, REG_PV, disp);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1330 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1331 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1332 disp = dseg_add_unique_double(cd, 0.0);
1333 M_CVTDL_C(s1, REG_FTMP2);
1334 M_DST(REG_FTMP2, REG_PV, disp);
1335 M_LLD(d, REG_PV, disp);
1336 emit_store_dst(jd, iptr, d);
1339 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1341 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1342 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1345 emit_store_dst(jd, iptr, d);
1348 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1350 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1351 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1358 emit_store_dst(jd, iptr, d);
1361 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1363 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1364 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1367 M_LSUB_IMM(REG_ZERO, 1, d);
1368 M_FCMPEQ(s1, s2, REG_FTMP3);
1369 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1371 M_FCMPLT(s2, s1, REG_FTMP3);
1372 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1373 M_LADD_IMM(REG_ZERO, 1, d);
1375 M_LSUB_IMM(REG_ZERO, 1, d);
1376 M_FCMPEQS(s1, s2, REG_FTMP3);
1378 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1380 M_FCMPLTS(s2, s1, REG_FTMP3);
1382 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1383 M_LADD_IMM(REG_ZERO, 1, d);
1385 emit_store_dst(jd, iptr, d);
1388 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1390 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1391 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1392 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1394 M_LADD_IMM(REG_ZERO, 1, d);
1395 M_FCMPEQ(s1, s2, REG_FTMP3);
1396 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1398 M_FCMPLT(s1, s2, REG_FTMP3);
1399 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1400 M_LSUB_IMM(REG_ZERO, 1, d);
1402 M_LADD_IMM(REG_ZERO, 1, d);
1403 M_FCMPEQS(s1, s2, REG_FTMP3);
1405 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1407 M_FCMPLTS(s1, s2, REG_FTMP3);
1409 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1410 M_LSUB_IMM(REG_ZERO, 1, d);
1412 emit_store_dst(jd, iptr, d);
1416 /* memory operations **************************************************/
1418 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1420 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1421 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1422 /* implicit null-pointer check */
1423 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1424 emit_store_dst(jd, iptr, d);
1427 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1429 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1430 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1431 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1432 /* implicit null-pointer check */
1433 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1434 if (has_ext_instr_set) {
1435 M_LADD(s2, s1, REG_ITMP1);
1436 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1440 M_LADD(s2, s1, REG_ITMP1);
1441 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1442 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1443 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1444 M_SRA_IMM(d, 56, d);
1446 emit_store_dst(jd, iptr, d);
1449 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1451 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1452 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1454 /* implicit null-pointer check */
1455 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1456 if (has_ext_instr_set) {
1457 M_LADD(s2, s1, REG_ITMP1);
1458 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1459 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1462 M_LADD (s2, s1, REG_ITMP1);
1463 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1464 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1465 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1466 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1468 emit_store_dst(jd, iptr, d);
1471 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1473 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1474 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1475 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1476 /* implicit null-pointer check */
1477 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1478 if (has_ext_instr_set) {
1479 M_LADD(s2, s1, REG_ITMP1);
1480 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1481 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1484 M_LADD(s2, s1, REG_ITMP1);
1485 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1486 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1487 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1488 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1489 M_SRA_IMM(d, 48, d);
1491 emit_store_dst(jd, iptr, d);
1494 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1496 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1497 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1499 /* implicit null-pointer check */
1500 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1501 M_S4ADDQ(s2, s1, REG_ITMP1);
1502 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1503 emit_store_dst(jd, iptr, d);
1506 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1508 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1509 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1511 /* implicit null-pointer check */
1512 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1513 M_S8ADDQ(s2, s1, REG_ITMP1);
1514 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1515 emit_store_dst(jd, iptr, d);
1518 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1521 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1522 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1523 /* implicit null-pointer check */
1524 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1525 M_S4ADDQ(s2, s1, REG_ITMP1);
1526 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1527 emit_store_dst(jd, iptr, d);
1530 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1533 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1534 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1535 /* implicit null-pointer check */
1536 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1537 M_S8ADDQ(s2, s1, REG_ITMP1);
1538 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1539 emit_store_dst(jd, iptr, d);
1542 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1545 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1547 /* implicit null-pointer check */
1548 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1549 M_SAADDQ(s2, s1, REG_ITMP1);
1550 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1551 emit_store_dst(jd, iptr, d);
1555 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1558 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1559 /* implicit null-pointer check */
1560 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1561 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1562 if (has_ext_instr_set) {
1563 M_LADD(s2, s1, REG_ITMP1);
1564 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1567 M_LADD(s2, s1, REG_ITMP1);
1568 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1569 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1570 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1571 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1572 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1573 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1577 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1580 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1581 /* implicit null-pointer check */
1582 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1583 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1584 if (has_ext_instr_set) {
1585 M_LADD(s2, s1, REG_ITMP1);
1586 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1587 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1590 M_LADD(s2, s1, REG_ITMP1);
1591 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1592 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1593 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1594 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1595 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1596 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1597 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1601 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1604 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1605 /* implicit null-pointer check */
1606 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1607 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1608 if (has_ext_instr_set) {
1609 M_LADD(s2, s1, REG_ITMP1);
1610 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1611 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1614 M_LADD(s2, s1, REG_ITMP1);
1615 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1616 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1617 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1618 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1619 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1620 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1621 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1625 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1629 /* implicit null-pointer check */
1630 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1631 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1632 M_S4ADDQ(s2, s1, REG_ITMP1);
1633 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1636 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1638 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1639 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1640 /* implicit null-pointer check */
1641 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1642 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1643 M_S8ADDQ(s2, s1, REG_ITMP1);
1644 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1647 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1651 /* implicit null-pointer check */
1652 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1653 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1654 M_S4ADDQ(s2, s1, REG_ITMP1);
1655 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1658 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1660 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1661 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1662 /* implicit null-pointer check */
1663 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1664 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1665 M_S8ADDQ(s2, s1, REG_ITMP1);
1666 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1669 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1671 s1 = emit_load_s1(jd, iptr, REG_A0);
1672 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1673 /* implicit null-pointer check */
1674 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1675 s3 = emit_load_s3(jd, iptr, REG_A1);
1677 M_INTMOVE(s1, REG_A0);
1678 M_INTMOVE(s3, REG_A1);
1680 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1681 M_ALD(REG_PV, REG_PV, disp);
1682 M_JSR(REG_RA, REG_PV);
1683 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1684 M_LDA(REG_PV, REG_RA, -disp);
1685 emit_exception_check(cd, iptr);
1687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1688 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1689 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1690 M_SAADDQ(s2, s1, REG_ITMP1);
1691 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1695 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1697 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1698 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1699 /* implicit null-pointer check */
1700 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1701 if (has_ext_instr_set) {
1702 M_LADD(s2, s1, REG_ITMP1);
1703 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1706 M_LADD(s2, s1, REG_ITMP1);
1707 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1708 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1709 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1710 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1711 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1712 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1716 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1718 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1719 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1720 /* implicit null-pointer check */
1721 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1722 if (has_ext_instr_set) {
1723 M_LADD(s2, s1, REG_ITMP1);
1724 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1725 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1728 M_LADD(s2, s1, REG_ITMP1);
1729 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1730 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1731 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1732 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1733 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1734 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1735 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1739 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1742 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1743 /* implicit null-pointer check */
1744 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1745 if (has_ext_instr_set) {
1746 M_LADD(s2, s1, REG_ITMP1);
1747 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1748 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1751 M_LADD(s2, s1, REG_ITMP1);
1752 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1753 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1754 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1755 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1756 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1757 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1758 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1762 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1765 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1766 /* implicit null-pointer check */
1767 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1768 M_S4ADDQ(s2, s1, REG_ITMP1);
1769 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1772 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1774 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1775 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1776 /* implicit null-pointer check */
1777 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1778 M_S8ADDQ(s2, s1, REG_ITMP1);
1779 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1782 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1786 /* implicit null-pointer check */
1787 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1788 M_SAADDQ(s2, s1, REG_ITMP1);
1789 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1793 case ICMD_GETSTATIC: /* ... ==> ..., value */
1795 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1796 uf = iptr->sx.s23.s3.uf;
1797 fieldtype = uf->fieldref->parseddesc.fd->type;
1798 disp = dseg_add_unique_address(cd, uf);
1800 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1803 fi = iptr->sx.s23.s3.fmiref->p.field;
1804 fieldtype = fi->type;
1805 disp = dseg_add_address(cd, &(fi->value));
1807 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1808 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1812 M_ALD(REG_ITMP1, REG_PV, disp);
1813 switch (fieldtype) {
1815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1816 M_ILD(d, REG_ITMP1, 0);
1819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1820 M_LLD(d, REG_ITMP1, 0);
1823 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1824 M_ALD(d, REG_ITMP1, 0);
1827 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1828 M_FLD(d, REG_ITMP1, 0);
1831 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1832 M_DLD(d, REG_ITMP1, 0);
1835 emit_store_dst(jd, iptr, d);
1838 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1840 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1841 uf = iptr->sx.s23.s3.uf;
1842 fieldtype = uf->fieldref->parseddesc.fd->type;
1843 disp = dseg_add_unique_address(cd, uf);
1845 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1848 fi = iptr->sx.s23.s3.fmiref->p.field;
1849 fieldtype = fi->type;
1850 disp = dseg_add_address(cd, &(fi->value));
1852 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1853 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1857 M_ALD(REG_ITMP1, REG_PV, disp);
1858 switch (fieldtype) {
1860 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1861 M_IST(s1, REG_ITMP1, 0);
1864 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1865 M_LST(s1, REG_ITMP1, 0);
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1869 M_AST(s1, REG_ITMP1, 0);
1872 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1873 M_FST(s1, REG_ITMP1, 0);
1876 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1877 M_DST(s1, REG_ITMP1, 0);
1882 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1883 /* val = value (in current instruction) */
1884 /* following NOP) */
1886 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1887 uf = iptr->sx.s23.s3.uf;
1888 fieldtype = uf->fieldref->parseddesc.fd->type;
1889 disp = dseg_add_unique_address(cd, uf);
1891 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1894 fi = iptr->sx.s23.s3.fmiref->p.field;
1895 fieldtype = fi->type;
1896 disp = dseg_add_address(cd, &(fi->value));
1898 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1899 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1903 M_ALD(REG_ITMP1, REG_PV, disp);
1904 switch (fieldtype) {
1906 M_IST(REG_ZERO, REG_ITMP1, 0);
1909 M_LST(REG_ZERO, REG_ITMP1, 0);
1912 M_AST(REG_ZERO, REG_ITMP1, 0);
1915 M_FST(REG_ZERO, REG_ITMP1, 0);
1918 M_DST(REG_ZERO, REG_ITMP1, 0);
1924 case ICMD_GETFIELD: /* ... ==> ..., value */
1926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1928 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1929 uf = iptr->sx.s23.s3.uf;
1930 fieldtype = uf->fieldref->parseddesc.fd->type;
1933 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1936 fi = iptr->sx.s23.s3.fmiref->p.field;
1937 fieldtype = fi->type;
1941 /* implicit null-pointer check */
1942 switch (fieldtype) {
1944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1948 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1952 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1956 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1960 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1964 emit_store_dst(jd, iptr, d);
1967 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1971 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1972 uf = iptr->sx.s23.s3.uf;
1973 fieldtype = uf->fieldref->parseddesc.fd->type;
1978 fi = iptr->sx.s23.s3.fmiref->p.field;
1979 fieldtype = fi->type;
1983 if (IS_INT_LNG_TYPE(fieldtype))
1984 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1986 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1988 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1989 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1991 /* implicit null-pointer check */
1992 switch (fieldtype) {
1994 M_IST(s2, s1, disp);
1997 M_LST(s2, s1, disp);
2000 M_AST(s2, s1, disp);
2003 M_FST(s2, s1, disp);
2006 M_DST(s2, s1, disp);
2011 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2012 /* val = value (in current instruction) */
2013 /* following NOP) */
2015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2017 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2018 uf = iptr->sx.s23.s3.uf;
2019 fieldtype = uf->fieldref->parseddesc.fd->type;
2022 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2025 fi = iptr->sx.s23.s3.fmiref->p.field;
2026 fieldtype = fi->type;
2030 /* implicit null-pointer check */
2031 switch (fieldtype) {
2033 M_IST(REG_ZERO, s1, disp);
2036 M_LST(REG_ZERO, s1, disp);
2039 M_AST(REG_ZERO, s1, disp);
2042 M_FST(REG_ZERO, s1, disp);
2045 M_DST(REG_ZERO, s1, disp);
2051 /* branch operations **************************************************/
2053 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2055 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2056 M_INTMOVE(s1, REG_ITMP1_XPTR);
2058 #ifdef ENABLE_VERIFIER
2059 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2060 unresolved_class *uc = iptr->sx.s23.s2.uc;
2062 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2064 #endif /* ENABLE_VERIFIER */
2066 disp = dseg_add_functionptr(cd, asm_handle_exception);
2067 M_ALD(REG_ITMP2, REG_PV, disp);
2068 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2069 M_NOP; /* nop ensures that XPC is less than the end */
2070 /* of basic block */
2074 case ICMD_GOTO: /* ... ==> ... */
2075 case ICMD_RET: /* ... ==> ... */
2077 emit_br(cd, iptr->dst.block);
2081 case ICMD_JSR: /* ... ==> ... */
2083 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2087 case ICMD_IFNULL: /* ..., value ==> ... */
2088 case ICMD_IFNONNULL:
2090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2091 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2094 case ICMD_IFEQ: /* ..., value ==> ... */
2096 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2097 if (iptr->sx.val.i == 0)
2098 emit_beqz(cd, iptr->dst.block, s1);
2100 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2101 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2103 ICONST(REG_ITMP2, iptr->sx.val.i);
2104 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2106 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2110 case ICMD_IFLT: /* ..., value ==> ... */
2112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2113 if (iptr->sx.val.i == 0)
2114 emit_bltz(cd, iptr->dst.block, s1);
2116 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2117 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2119 ICONST(REG_ITMP2, iptr->sx.val.i);
2120 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2122 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2126 case ICMD_IFLE: /* ..., value ==> ... */
2128 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2129 if (iptr->sx.val.i == 0)
2130 emit_blez(cd, iptr->dst.block, s1);
2132 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2133 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2135 ICONST(REG_ITMP2, iptr->sx.val.i);
2136 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2138 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2142 case ICMD_IFNE: /* ..., value ==> ... */
2144 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2145 if (iptr->sx.val.i == 0)
2146 emit_bnez(cd, iptr->dst.block, s1);
2148 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2149 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2151 ICONST(REG_ITMP2, iptr->sx.val.i);
2152 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2154 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2158 case ICMD_IFGT: /* ..., value ==> ... */
2160 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2161 if (iptr->sx.val.i == 0)
2162 emit_bgtz(cd, iptr->dst.block, s1);
2164 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2165 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2167 ICONST(REG_ITMP2, iptr->sx.val.i);
2168 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2170 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2174 case ICMD_IFGE: /* ..., value ==> ... */
2176 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2177 if (iptr->sx.val.i == 0)
2178 emit_bgez(cd, iptr->dst.block, s1);
2180 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255))
2181 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2183 ICONST(REG_ITMP2, iptr->sx.val.i);
2184 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2186 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2190 case ICMD_IF_LEQ: /* ..., value ==> ... */
2192 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2193 if (iptr->sx.val.l == 0)
2194 emit_beqz(cd, iptr->dst.block, s1);
2196 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2197 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2199 LCONST(REG_ITMP2, iptr->sx.val.l);
2200 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2202 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2206 case ICMD_IF_LLT: /* ..., value ==> ... */
2208 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2209 if (iptr->sx.val.l == 0)
2210 emit_bltz(cd, iptr->dst.block, s1);
2212 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2213 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2215 LCONST(REG_ITMP2, iptr->sx.val.l);
2216 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2218 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2222 case ICMD_IF_LLE: /* ..., value ==> ... */
2224 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2225 if (iptr->sx.val.l == 0)
2226 emit_blez(cd, iptr->dst.block, s1);
2228 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2229 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2231 LCONST(REG_ITMP2, iptr->sx.val.l);
2232 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2234 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2238 case ICMD_IF_LNE: /* ..., value ==> ... */
2240 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2241 if (iptr->sx.val.l == 0)
2242 emit_bnez(cd, iptr->dst.block, s1);
2244 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2245 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2247 LCONST(REG_ITMP2, iptr->sx.val.l);
2248 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2250 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2254 case ICMD_IF_LGT: /* ..., value ==> ... */
2256 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2257 if (iptr->sx.val.l == 0)
2258 emit_bgtz(cd, iptr->dst.block, s1);
2260 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2261 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2263 LCONST(REG_ITMP2, iptr->sx.val.l);
2264 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2266 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2270 case ICMD_IF_LGE: /* ..., value ==> ... */
2272 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2273 if (iptr->sx.val.l == 0)
2274 emit_bgez(cd, iptr->dst.block, s1);
2276 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255))
2277 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2279 LCONST(REG_ITMP2, iptr->sx.val.l);
2280 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2282 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2286 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2287 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2288 case ICMD_IF_ACMPEQ:
2290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2291 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2292 M_CMPEQ(s1, s2, REG_ITMP1);
2293 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2296 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2297 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2298 case ICMD_IF_ACMPNE:
2300 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2302 M_CMPEQ(s1, s2, REG_ITMP1);
2303 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2306 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2307 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2310 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2311 M_CMPLT(s1, s2, REG_ITMP1);
2312 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2315 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2316 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2319 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2320 M_CMPLE(s1, s2, REG_ITMP1);
2321 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2324 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2325 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2328 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2329 M_CMPLE(s1, s2, REG_ITMP1);
2330 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2333 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2334 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2336 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2337 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2338 M_CMPLT(s1, s2, REG_ITMP1);
2339 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2343 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2346 REPLACEMENT_POINT_RETURN(cd, iptr);
2347 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2348 M_INTMOVE(s1, REG_RESULT);
2349 goto nowperformreturn;
2351 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2353 REPLACEMENT_POINT_RETURN(cd, iptr);
2354 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2355 M_INTMOVE(s1, REG_RESULT);
2357 #ifdef ENABLE_VERIFIER
2358 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2359 unresolved_class *uc = iptr->sx.s23.s2.uc;
2361 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2363 #endif /* ENABLE_VERIFIER */
2364 goto nowperformreturn;
2366 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2369 REPLACEMENT_POINT_RETURN(cd, iptr);
2370 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2371 M_FLTMOVE(s1, REG_FRESULT);
2372 goto nowperformreturn;
2374 case ICMD_RETURN: /* ... ==> ... */
2376 REPLACEMENT_POINT_RETURN(cd, iptr);
2382 p = cd->stackframesize;
2384 /* call trace function */
2386 #if !defined(NDEBUG)
2387 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2388 emit_verbosecall_exit(jd);
2391 #if defined(ENABLE_THREADS)
2392 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2393 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2395 switch (iptr->opc) {
2399 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2403 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2407 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2408 M_ALD(REG_PV, REG_PV, disp);
2409 M_JSR(REG_RA, REG_PV);
2410 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2411 M_LDA(REG_PV, REG_RA, disp);
2413 switch (iptr->opc) {
2417 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2421 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2427 /* restore return address */
2429 if (!jd->isleafmethod) {
2430 p--; M_LLD(REG_RA, REG_SP, p * 8);
2433 /* restore saved registers */
2435 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2436 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2438 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2439 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2442 /* deallocate stack */
2444 if (cd->stackframesize)
2445 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2447 M_RET(REG_ZERO, REG_RA);
2453 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2456 branch_target_t *table;
2458 table = iptr->dst.table;
2460 l = iptr->sx.s23.s2.tablelow;
2461 i = iptr->sx.s23.s3.tablehigh;
2463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2465 M_INTMOVE(s1, REG_ITMP1);
2466 } else if (l <= 32768) {
2467 M_LDA(REG_ITMP1, s1, -l);
2469 ICONST(REG_ITMP2, l);
2470 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2473 /* number of targets */
2479 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2481 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2482 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2484 emit_beqz(cd, table[0].block, REG_ITMP2);
2486 /* build jump table top down and use address of lowest entry */
2491 dseg_add_target(cd, table->block);
2496 /* length of dataseg after last dseg_add_target is used by load */
2498 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2499 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2500 M_JMP(REG_ZERO, REG_ITMP2);
2505 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2508 lookup_target_t *lookup;
2510 lookup = iptr->dst.lookup;
2512 i = iptr->sx.s23.s2.lookupcount;
2514 MCODECHECK((i<<2)+8);
2515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2518 val = lookup->value;
2519 if ((val >= 0) && (val <= 255)) {
2520 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2522 if ((val >= -32768) && (val <= 32767)) {
2523 M_LDA(REG_ITMP2, REG_ZERO, val);
2525 disp = dseg_add_s4(cd, val);
2526 M_ILD(REG_ITMP2, REG_PV, disp);
2528 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2530 emit_bnez(cd, lookup->target.block, REG_ITMP2);
2534 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2540 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2542 bte = iptr->sx.s23.s3.bte;
2546 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2548 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2549 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2550 case ICMD_INVOKEINTERFACE:
2552 REPLACEMENT_POINT_INVOKE(cd, iptr);
2554 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2556 um = iptr->sx.s23.s3.um;
2557 md = um->methodref->parseddesc.md;
2560 lm = iptr->sx.s23.s3.fmiref->p.method;
2562 md = lm->parseddesc;
2566 s3 = md->paramcount;
2568 MCODECHECK((s3 << 1) + 64);
2570 /* copy arguments to registers or stack location */
2572 for (s3 = s3 - 1; s3 >= 0; s3--) {
2573 var = VAR(iptr->sx.s23.s2.args[s3]);
2574 d = md->params[s3].regoff;
2576 /* already preallocated (ARGVAR)? */
2578 if (var->flags & PREALLOC)
2581 if (IS_INT_LNG_TYPE(var->type)) {
2582 if (!md->params[s3].inmemory) {
2583 s1 = emit_load(jd, iptr, var, d);
2587 s1 = emit_load(jd, iptr, var, REG_ITMP1);
2588 M_LST(s1, REG_SP, d * 8);
2592 if (!md->params[s3].inmemory) {
2593 s1 = emit_load(jd, iptr, var, d);
2597 s1 = emit_load(jd, iptr, var, REG_FTMP1);
2598 M_DST(s1, REG_SP, d * 8);
2603 switch (iptr->opc) {
2605 disp = dseg_add_functionptr(cd, bte->fp);
2607 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2609 /* generate the actual call */
2611 M_JSR(REG_RA, REG_PV);
2612 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2613 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2614 M_LDA(REG_PV, REG_RA, -disp);
2616 emit_exception_check(cd, iptr);
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 codegen_add_patch_ref(cd, 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 codegen_add_patch_ref(cd, 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_objectheader, 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 codegen_add_patch_ref(cd, 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_objectheader, 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 /* val.a: (classinfo*) superclass */
2715 /* superclass is an interface:
2717 * OK if ((sub == NULL) ||
2718 * (sub->vftbl->interfacetablelength > super->index) &&
2719 * (sub->vftbl->interfacetable[-super->index] != NULL));
2721 * superclass is a class:
2723 * OK if ((sub == NULL) || (0
2724 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2725 * super->vftbl->diffval));
2728 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2729 /* object type cast-check */
2732 vftbl_t *supervftbl;
2735 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2741 super = iptr->sx.s23.s3.c.cls;
2742 superindex = super->index;
2743 supervftbl = super->vftbl;
2746 #if defined(ENABLE_THREADS)
2747 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2749 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2751 /* if class is not resolved, check which code to call */
2753 if (super == NULL) {
2754 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2756 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2758 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2759 iptr->sx.s23.s3.c.ref,
2762 M_ILD(REG_ITMP2, REG_PV, disp);
2763 disp = dseg_add_s4(cd, ACC_INTERFACE);
2764 M_ILD(REG_ITMP3, REG_PV, disp);
2765 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2766 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
2769 /* interface checkcast code */
2771 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2772 if (super == NULL) {
2773 codegen_add_patch_ref(cd,
2774 PATCHER_checkcast_interface,
2775 iptr->sx.s23.s3.c.ref,
2779 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2781 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2782 M_ILD(REG_ITMP3, REG_ITMP2,
2783 OFFSET(vftbl_t, interfacetablelength));
2784 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2785 emit_classcast_check(cd, iptr, BRANCH_LE, REG_ITMP3, s1);
2787 M_ALD(REG_ITMP3, REG_ITMP2,
2788 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2789 superindex * sizeof(methodptr*)));
2790 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2793 emit_label_br(cd, BRANCH_LABEL_4);
2795 emit_label(cd, BRANCH_LABEL_3);
2798 /* class checkcast code */
2800 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2801 if (super == NULL) {
2802 emit_label(cd, BRANCH_LABEL_2);
2804 disp = dseg_add_unique_address(cd, NULL);
2806 codegen_add_patch_ref(cd,
2807 PATCHER_resolve_classref_to_vftbl,
2808 iptr->sx.s23.s3.c.ref,
2812 disp = dseg_add_address(cd, supervftbl);
2814 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
2817 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2818 M_ALD(REG_ITMP3, REG_PV, disp);
2819 #if defined(ENABLE_THREADS)
2820 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2822 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2823 /* if (s1 != REG_ITMP1) { */
2824 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2825 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2826 /* #if defined(ENABLE_THREADS) */
2827 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2829 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2832 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2833 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2834 M_ALD(REG_ITMP3, REG_PV, disp);
2835 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2836 #if defined(ENABLE_THREADS)
2837 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2840 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2841 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_ITMP3, s1);
2844 emit_label(cd, BRANCH_LABEL_5);
2847 if (super == NULL) {
2848 emit_label(cd, BRANCH_LABEL_1);
2849 emit_label(cd, BRANCH_LABEL_4);
2852 d = codegen_reg_of_dst(jd, iptr, s1);
2855 /* array type cast-check */
2857 s1 = emit_load_s1(jd, iptr, REG_A0);
2858 M_INTMOVE(s1, REG_A0);
2860 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2861 disp = dseg_add_unique_address(cd, NULL);
2863 codegen_add_patch_ref(cd,
2864 PATCHER_resolve_classref_to_classinfo,
2865 iptr->sx.s23.s3.c.ref,
2869 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2871 M_ALD(REG_A1, REG_PV, disp);
2872 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2873 M_ALD(REG_PV, REG_PV, disp);
2874 M_JSR(REG_RA, REG_PV);
2875 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2876 M_LDA(REG_PV, REG_RA, -disp);
2878 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2879 emit_classcast_check(cd, iptr, BRANCH_EQ, REG_RESULT, s1);
2881 d = codegen_reg_of_dst(jd, iptr, s1);
2885 emit_store_dst(jd, iptr, d);
2888 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2890 /* val.a: (classinfo*) superclass */
2892 /* superclass is an interface:
2894 * return (sub != NULL) &&
2895 * (sub->vftbl->interfacetablelength > super->index) &&
2896 * (sub->vftbl->interfacetable[-super->index] != NULL);
2898 * superclass is a class:
2900 * return ((sub != NULL) && (0
2901 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2902 * super->vftbl->diffvall));
2907 vftbl_t *supervftbl;
2910 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2916 super = iptr->sx.s23.s3.c.cls;
2917 superindex = super->index;
2918 supervftbl = super->vftbl;
2921 #if defined(ENABLE_THREADS)
2922 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2924 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2925 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2928 M_MOV(s1, REG_ITMP1);
2932 /* if class is not resolved, check which code to call */
2934 if (super == NULL) {
2936 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
2938 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2940 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2941 iptr->sx.s23.s3.c.ref, disp);
2943 M_ILD(REG_ITMP3, REG_PV, disp);
2945 disp = dseg_add_s4(cd, ACC_INTERFACE);
2946 M_ILD(REG_ITMP2, REG_PV, disp);
2947 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2948 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
2951 /* interface instanceof code */
2953 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2954 if (super == NULL) {
2955 /* If d == REG_ITMP2, then it's destroyed in check
2960 codegen_add_patch_ref(cd,
2961 PATCHER_instanceof_interface,
2962 iptr->sx.s23.s3.c.ref, 0);
2966 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
2969 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2970 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2971 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2972 M_BLEZ(REG_ITMP3, 2);
2973 M_ALD(REG_ITMP1, REG_ITMP1,
2974 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2975 superindex * sizeof(methodptr*)));
2976 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
2979 emit_label_br(cd, BRANCH_LABEL_4);
2981 emit_label(cd, BRANCH_LABEL_3);
2984 /* class instanceof code */
2986 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2987 if (super == NULL) {
2988 emit_label(cd, BRANCH_LABEL_2);
2990 disp = dseg_add_unique_address(cd, NULL);
2992 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
2993 iptr->sx.s23.s3.c.ref,
2997 disp = dseg_add_address(cd, supervftbl);
3000 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3003 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3004 M_ALD(REG_ITMP2, REG_PV, disp);
3005 #if defined(ENABLE_THREADS)
3006 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3008 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3009 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3010 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3011 #if defined(ENABLE_THREADS)
3012 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3014 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3015 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3018 emit_label(cd, BRANCH_LABEL_5);
3021 if (super == NULL) {
3022 emit_label(cd, BRANCH_LABEL_1);
3023 emit_label(cd, BRANCH_LABEL_4);
3026 emit_store_dst(jd, iptr, d);
3030 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3032 /* check for negative sizes and copy sizes to stack if necessary */
3034 MCODECHECK((iptr->s1.argcount << 1) + 64);
3036 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3038 var = VAR(iptr->sx.s23.s2.args[s1]);
3040 /* copy SAVEDVAR sizes to stack */
3042 /* Already Preallocated? */
3044 if (!(var->flags & PREALLOC)) {
3045 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3046 M_LST(s2, REG_SP, s1 * 8);
3050 /* a0 = dimension count */
3052 ICONST(REG_A0, iptr->s1.argcount);
3054 /* is patcher function set? */
3056 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3057 disp = dseg_add_unique_address(cd, 0);
3059 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
3060 iptr->sx.s23.s3.c.ref,
3064 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3066 /* a1 = arraydescriptor */
3068 M_ALD(REG_A1, REG_PV, disp);
3070 /* a2 = pointer to dimensions = stack pointer */
3072 M_INTMOVE(REG_SP, REG_A2);
3074 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3075 M_ALD(REG_PV, REG_PV, disp);
3076 M_JSR(REG_RA, REG_PV);
3077 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3078 M_LDA(REG_PV, REG_RA, -disp);
3080 /* check for exception before result assignment */
3082 emit_exception_check(cd, iptr);
3084 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3085 M_INTMOVE(REG_RESULT, d);
3086 emit_store_dst(jd, iptr, d);
3090 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3095 } /* for instruction */
3097 } /* if (bptr -> flags >= BBREACHED) */
3098 } /* for basic block */
3100 dseg_createlinenumbertable(cd);
3102 /* generate stubs */
3104 emit_patcher_stubs(jd);
3105 REPLACEMENT_EMIT_STUBS(jd);
3107 /* everything's ok */
3113 /* codegen_emit_stub_compiler **************************************************
3115 Emits a stub routine which calls the compiler.
3117 *******************************************************************************/
3119 void codegen_emit_stub_compiler(jitdata *jd)
3124 /* get required compiler data */
3129 /* code for the stub */
3131 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3132 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3133 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3137 /* codegen_emit_stub_native ****************************************************
3139 Emits a stub routine which calls a native method.
3141 *******************************************************************************/
3143 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f)
3150 s4 i, j; /* count variables */
3153 s4 funcdisp; /* displacement of the function */
3155 /* get required compiler data */
3161 /* initialize variables */
3164 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3166 /* calculate stack frame size */
3168 cd->stackframesize =
3169 1 + /* return address */
3170 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3171 sizeof(localref_table) / SIZEOF_VOID_P +
3172 1 + /* methodinfo for call trace */
3173 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
3176 /* create method header */
3178 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3179 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3180 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3181 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3182 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3183 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3184 (void) dseg_addlinenumbertablesize(cd);
3185 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3187 /* generate stub code */
3189 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3190 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3192 /* call trace function */
3194 #if !defined(NDEBUG)
3195 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3196 emit_verbosecall_enter(jd);
3199 /* get function address (this must happen before the stackframeinfo) */
3201 funcdisp = dseg_add_functionptr(cd, f);
3203 #if !defined(WITH_STATIC_CLASSPATH)
3205 codegen_add_patch_ref(cd, PATCHER_resolve_native_function, m, funcdisp);
3208 #if defined(ENABLE_GC_CACAO)
3209 /* Save callee saved integer registers in stackframeinfo (GC may
3210 need to recover them during a collection). */
3212 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3213 OFFSET(stackframeinfo, intregs);
3215 for (i = 0; i < INT_SAV_CNT; i++)
3216 M_AST(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3219 /* save integer and float argument registers */
3221 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3222 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3223 M_LST(abi_registers_integer_argument[i], REG_SP, j * 8);
3228 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3229 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3230 M_DST(abi_registers_float_argument[i], REG_SP, j * 8);
3235 /* prepare data structures for native function call */
3237 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3238 M_MOV(REG_PV, REG_A1);
3239 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3240 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3241 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3242 M_ALD(REG_PV, REG_PV, disp);
3243 M_JSR(REG_RA, REG_PV);
3244 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3245 M_LDA(REG_PV, REG_RA, -disp);
3247 /* restore integer and float argument registers */
3249 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3250 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3251 M_LLD(abi_registers_integer_argument[i], REG_SP, j * 8);
3256 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3257 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3258 M_DLD(abi_registers_float_argument[i], REG_SP, j * 8);
3263 /* copy or spill arguments to new locations */
3265 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3266 t = md->paramtypes[i].type;
3268 if (IS_INT_LNG_TYPE(t)) {
3269 if (!md->params[i].inmemory) {
3270 s1 = md->params[i].regoff;
3271 s2 = nmd->params[j].regoff;
3273 if (!nmd->params[j].inmemory)
3276 M_LST(s1, REG_SP, s2 * 8);
3279 s1 = md->params[i].regoff + cd->stackframesize;
3280 s2 = nmd->params[j].regoff;
3281 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3282 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3286 if (!md->params[i].inmemory) {
3287 s1 = md->params[i].regoff;
3288 s2 = nmd->params[j].regoff;
3290 if (!nmd->params[j].inmemory)
3293 if (IS_2_WORD_TYPE(t))
3294 M_DST(s1, REG_SP, s2 * 8);
3296 M_FST(s1, REG_SP, s2 * 8);
3300 s1 = md->params[i].regoff + cd->stackframesize;
3301 s2 = nmd->params[j].regoff;
3302 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3303 if (IS_2_WORD_TYPE(t))
3304 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3306 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3311 /* put class into second argument register */
3313 if (m->flags & ACC_STATIC) {
3314 disp = dseg_add_address(cd, m->class);
3315 M_ALD(REG_A1, REG_PV, disp);
3318 /* put env into first argument register */
3320 disp = dseg_add_address(cd, _Jv_env);
3321 M_ALD(REG_A0, REG_PV, disp);
3323 /* do the native function call */
3325 M_ALD(REG_PV, REG_PV, funcdisp);
3326 M_JSR(REG_RA, REG_PV); /* call native method */
3327 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3328 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3330 /* save return value */
3332 switch (md->returntype.type) {
3336 M_LST(REG_RESULT, REG_SP, 0 * 8);
3340 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3346 /* call finished trace */
3348 #if !defined(NDEBUG)
3349 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3350 emit_verbosecall_exit(jd);
3353 /* remove native stackframe info */
3355 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3356 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3357 M_ALD(REG_PV, REG_PV, disp);
3358 M_JSR(REG_RA, REG_PV);
3359 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3360 M_LDA(REG_PV, REG_RA, -disp);
3361 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3363 /* restore return value */
3365 switch (md->returntype.type) {
3369 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3373 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3379 #if defined(ENABLE_GC_CACAO)
3380 /* Restore callee saved integer registers from stackframeinfo (GC
3381 might have modified them during a collection). */
3383 disp = cd->stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo) +
3384 OFFSET(stackframeinfo, intregs);
3386 for (i = 0; i < INT_SAV_CNT; i++)
3387 M_ALD(abi_registers_integer_saved[i], REG_SP, disp + i * 8);
3390 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3391 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3393 /* check for exception */
3395 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3396 M_RET(REG_ZERO, REG_RA); /* return to caller */
3398 /* handle exception */
3400 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3402 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3403 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3404 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3406 /* generate patcher stubs */
3408 emit_patcher_stubs(jd);
3413 * These are local overrides for various environment variables in Emacs.
3414 * Please do not remove this and leave it at the end of the file, where
3415 * Emacs will automagically detect them.
3416 * ---------------------------------------------------------------------
3419 * indent-tabs-mode: t
3423 * vim:noexpandtab:sw=4:ts=4: