1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
34 $Id: codegen.c 5982 2006-11-15 15:30:36Z twisti $
49 #include "vm/jit/alpha/arch.h"
50 #include "vm/jit/alpha/codegen.h"
52 #include "native/jni.h"
53 #include "native/native.h"
55 #if defined(ENABLE_THREADS)
56 # include "threads/native/lock.h"
59 #include "vm/builtin.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/codegen-common.h"
68 #include "vm/jit/dseg.h"
69 #include "vm/jit/emit-common.h"
70 #include "vm/jit/jit.h"
71 #include "vm/jit/parse.h"
72 #include "vm/jit/patcher.h"
73 #include "vm/jit/reg.h"
74 #include "vm/jit/replace.h"
76 #if defined(ENABLE_LSRA)
77 # include "vm/jit/allocator/lsra.h"
81 /* codegen *********************************************************************
83 Generates machine code.
85 *******************************************************************************/
87 bool codegen(jitdata *jd)
93 s4 len, s1, s2, s3, d, disp;
99 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
100 unresolved_method *um;
101 builtintable_entry *bte;
104 unresolved_field *uf;
105 rplpoint *replacementpoint;
109 /* get required compiler data */
116 /* prevent compiler warnings */
129 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
131 /* space to save used callee saved registers */
133 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
134 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
136 cd->stackframesize = rd->memuse + savedregs_num;
138 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
139 if (checksync && (m->flags & ACC_SYNCHRONIZED))
140 cd->stackframesize++;
143 /* create method header */
146 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
149 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
150 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
152 #if defined(ENABLE_THREADS)
153 /* IsSync contains the offset relative to the stack pointer for the
154 argument of monitor_exit used in the exception handler. Since the
155 offset could be zero and give a wrong meaning of the flag it is
159 if (checksync && (m->flags & ACC_SYNCHRONIZED))
160 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
163 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
165 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
166 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
167 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
169 dseg_addlinenumbertablesize(cd);
171 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
173 /* create exception table */
175 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
176 dseg_add_target(cd, ex->start);
177 dseg_add_target(cd, ex->end);
178 dseg_add_target(cd, ex->handler);
179 (void) dseg_add_unique_address(cd, ex->catchtype.any);
182 /* create stack frame (if necessary) */
184 if (cd->stackframesize)
185 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
187 /* save return address and used callee saved registers */
189 p = cd->stackframesize;
190 if (!jd->isleafmethod) {
191 p--; M_AST(REG_RA, REG_SP, p * 8);
193 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
194 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
196 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
197 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
200 /* take arguments out of register or stack frame */
204 for (p = 0, l = 0; p < md->paramcount; p++) {
205 t = md->paramtypes[p].type;
207 varindex = jd->local_map[l * 5 + t];
210 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
213 if (varindex == UNUSED)
218 s1 = md->params[p].regoff;
220 if (IS_INT_LNG_TYPE(t)) { /* integer args */
221 if (!md->params[p].inmemory) { /* register arguments */
222 s2 = rd->argintregs[s1];
223 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
224 M_INTMOVE(s2, var->vv.regoff);
226 } else { /* reg arg -> spilled */
227 M_LST(s2, REG_SP, var->vv.regoff * 8);
230 } else { /* stack arguments */
231 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
232 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) *8);
234 } else { /* stack arg -> spilled */
235 var->vv.regoff = cd->stackframesize + s1;
239 } else { /* floating args */
240 if (!md->params[p].inmemory) { /* register arguments */
241 s2 = rd->argfltregs[s1];
242 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
243 M_FLTMOVE(s2, var->vv.regoff);
245 } else { /* reg arg -> spilled */
246 M_DST(s2, REG_SP, var->vv.regoff * 8);
249 } else { /* stack arguments */
250 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
251 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
253 } else { /* stack-arg -> spilled */
254 var->vv.regoff = cd->stackframesize + s1;
260 /* call monitorenter function */
262 #if defined(ENABLE_THREADS)
263 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
264 /* stack offset for monitor argument */
269 if (opt_verbosecall) {
270 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
272 for (p = 0; p < INT_ARG_CNT; p++)
273 M_LST(rd->argintregs[p], REG_SP, p * 8);
275 for (p = 0; p < FLT_ARG_CNT; p++)
276 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
278 s1 += INT_ARG_CNT + FLT_ARG_CNT;
280 #endif /* !defined(NDEBUG) */
282 /* decide which monitor enter function to call */
284 if (m->flags & ACC_STATIC) {
285 disp = dseg_add_address(cd, &m->class->object.header);
286 M_ALD(REG_A0, REG_PV, disp);
290 codegen_add_nullpointerexception_ref(cd);
293 M_AST(REG_A0, REG_SP, s1 * 8);
294 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
295 M_ALD(REG_PV, REG_PV, disp);
296 M_JSR(REG_RA, REG_PV);
297 disp = (s4) (cd->mcodeptr - cd->mcodebase);
298 M_LDA(REG_PV, REG_RA, -disp);
301 if (opt_verbosecall) {
302 for (p = 0; p < INT_ARG_CNT; p++)
303 M_LLD(rd->argintregs[p], REG_SP, p * 8);
305 for (p = 0; p < FLT_ARG_CNT; p++)
306 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
308 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
310 #endif /* !defined(NDEBUG) */
314 /* call trace function */
317 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
318 emit_verbosecall_enter(jd);
323 /* end of header generation */
325 replacementpoint = jd->code->rplpoints;
327 /* walk through all basic blocks */
329 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
331 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
333 if (bptr->flags >= BBREACHED) {
335 /* branch resolving */
337 codegen_resolve_branchrefs(cd, bptr);
339 /* handle replacement points */
342 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
343 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
349 /* copy interface registers to their destination */
353 #if defined(ENABLE_LSRA)
357 src = bptr->invars[len];
358 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
359 /* d = reg_of_var(m, src, REG_ITMP1); */
360 if (!(src->flags & INMEMORY))
364 M_INTMOVE(REG_ITMP1, d);
365 emit_store(jd, NULL, src, d);
372 var = VAR(bptr->invars[len]);
373 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
374 d = codegen_reg_of_var(0, var, REG_ITMP1);
375 M_INTMOVE(REG_ITMP1, d);
376 emit_store(jd, NULL, var, d);
379 assert((var->flags & INOUT));
382 #if defined(ENABLE_LSRA)
386 /* walk through all instructions */
390 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
391 if (iptr->line != currentline) {
392 dseg_addlinenumber(cd, iptr->line);
393 currentline = iptr->line;
396 MCODECHECK(64); /* an instruction usually needs < 64 words */
399 case ICMD_INLINE_START:
400 case ICMD_INLINE_END:
403 case ICMD_NOP: /* ... ==> ... */
406 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
408 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
410 codegen_add_nullpointerexception_ref(cd);
413 /* constant operations ************************************************/
415 case ICMD_ICONST: /* ... ==> ..., constant */
417 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
418 ICONST(d, iptr->sx.val.i);
419 emit_store_dst(jd, iptr, d);
422 case ICMD_LCONST: /* ... ==> ..., constant */
424 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
425 LCONST(d, iptr->sx.val.l);
426 emit_store_dst(jd, iptr, d);
429 case ICMD_FCONST: /* ... ==> ..., constant */
431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
432 disp = dseg_add_float(cd, iptr->sx.val.f);
433 M_FLD(d, REG_PV, disp);
434 emit_store_dst(jd, iptr, d);
437 case ICMD_DCONST: /* ... ==> ..., constant */
439 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
440 disp = dseg_add_double(cd, iptr->sx.val.d);
441 M_DLD(d, REG_PV, disp);
442 emit_store_dst(jd, iptr, d);
445 case ICMD_ACONST: /* ... ==> ..., constant */
447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
449 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
450 constant_classref *cr = iptr->sx.val.c.ref;
452 disp = dseg_add_unique_address(cd, cr);
454 /* XXX Only add the patcher, if this position needs to
455 be patched. If there was a previous position which
456 resolved the same class, the returned displacement
457 of dseg_addaddress is ok to use. */
459 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
462 M_ALD(d, REG_PV, disp);
465 if (iptr->sx.val.anyptr == NULL)
466 M_INTMOVE(REG_ZERO, d);
468 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
469 M_ALD(d, REG_PV, disp);
472 emit_store_dst(jd, iptr, d);
476 /* load/store/move/copy operations ************************************/
478 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
479 case ICMD_ALOAD: /* s1 = local variable */
483 case ICMD_ISTORE: /* ..., value ==> ... */
484 case ICMD_ASTORE: /* dst = local variable */
491 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
495 /* pop operations *****************************************************/
497 /* attention: double and longs are only one entry in CACAO ICMDs */
499 case ICMD_POP: /* ..., value ==> ... */
500 case ICMD_POP2: /* ..., value, value ==> ... */
505 /* integer operations *************************************************/
507 case ICMD_INEG: /* ..., value ==> ..., - value */
509 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
511 M_ISUB(REG_ZERO, s1, d);
512 emit_store_dst(jd, iptr, d);
515 case ICMD_LNEG: /* ..., value ==> ..., - value */
517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
519 M_LSUB(REG_ZERO, s1, d);
520 emit_store_dst(jd, iptr, d);
523 case ICMD_I2L: /* ..., value ==> ..., value */
525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
528 emit_store_dst(jd, iptr, d);
531 case ICMD_L2I: /* ..., value ==> ..., value */
533 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
535 M_IADD(s1, REG_ZERO, d);
536 emit_store_dst(jd, iptr, d);
539 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
543 if (has_ext_instr_set) {
546 M_SLL_IMM(s1, 56, d);
547 M_SRA_IMM( d, 56, d);
549 emit_store_dst(jd, iptr, d);
552 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
555 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
557 emit_store_dst(jd, iptr, d);
560 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 if (has_ext_instr_set) {
567 M_SLL_IMM(s1, 48, d);
568 M_SRA_IMM( d, 48, d);
570 emit_store_dst(jd, iptr, d);
574 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
578 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
580 emit_store_dst(jd, iptr, d);
584 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
585 /* sx.val.i = constant */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
590 M_IADD_IMM(s1, iptr->sx.val.i, d);
591 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
592 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
594 /* XXX maybe use M_LDA? */
595 ICONST(REG_ITMP2, iptr->sx.val.i);
596 M_IADD(s1, REG_ITMP2, d);
598 emit_store_dst(jd, iptr, d);
601 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
604 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
605 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
607 emit_store_dst(jd, iptr, d);
610 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
611 /* sx.val.l = constant */
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
615 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
616 M_LADD_IMM(s1, iptr->sx.val.l, d);
618 LCONST(REG_ITMP2, iptr->sx.val.l);
619 M_LADD(s1, REG_ITMP2, d);
621 emit_store_dst(jd, iptr, d);
624 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
628 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
630 emit_store_dst(jd, iptr, d);
633 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
634 /* sx.val.i = constant */
636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
638 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
639 M_ISUB_IMM(s1, iptr->sx.val.i, d);
641 ICONST(REG_ITMP2, iptr->sx.val.i);
642 M_ISUB(s1, REG_ITMP2, d);
644 emit_store_dst(jd, iptr, d);
647 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
653 emit_store_dst(jd, iptr, d);
656 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
657 /* sx.val.l = constant */
659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
662 M_LSUB_IMM(s1, iptr->sx.val.l, d);
664 LCONST(REG_ITMP2, iptr->sx.val.l);
665 M_LSUB(s1, REG_ITMP2, d);
667 emit_store_dst(jd, iptr, d);
670 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
676 emit_store_dst(jd, iptr, d);
679 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
680 /* sx.val.i = constant */
682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
685 M_IMUL_IMM(s1, iptr->sx.val.i, d);
687 ICONST(REG_ITMP2, iptr->sx.val.i);
688 M_IMUL(s1, REG_ITMP2, d);
690 emit_store_dst(jd, iptr, d);
693 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
697 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
699 emit_store_dst(jd, iptr, d);
702 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
703 /* sx.val.l = constant */
705 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
706 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
707 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
708 M_LMUL_IMM(s1, iptr->sx.val.l, d);
710 LCONST(REG_ITMP2, iptr->sx.val.l);
711 M_LMUL(s1, REG_ITMP2, d);
713 emit_store_dst(jd, iptr, d);
716 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
717 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
719 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
720 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
721 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
723 codegen_add_arithmeticexception_ref(cd);
727 bte = iptr->sx.s23.s3.bte;
728 disp = dseg_add_functionptr(cd, bte->fp);
729 M_ALD(REG_PV, REG_PV, disp);
730 M_JSR(REG_RA, REG_PV);
731 disp = (s4) (cd->mcodeptr - cd->mcodebase);
732 M_LDA(REG_PV, REG_RA, -disp);
734 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
735 emit_store_dst(jd, iptr, d);
738 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
739 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
741 bte = iptr->sx.s23.s3.bte;
743 s1 = emit_load_s1(jd, iptr, REG_A0);
744 s2 = emit_load_s2(jd, iptr, REG_A1);
745 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
747 codegen_add_arithmeticexception_ref(cd);
749 M_INTMOVE(s1, REG_A0);
750 M_INTMOVE(s2, REG_A1);
751 disp = dseg_add_functionptr(cd, bte->fp);
752 M_ALD(REG_PV, REG_PV, disp);
753 M_JSR(REG_RA, REG_PV);
754 disp = (s4) (cd->mcodeptr - cd->mcodebase);
755 M_LDA(REG_PV, REG_RA, -disp);
757 M_INTMOVE(REG_RESULT, d);
758 emit_store_dst(jd, iptr, d);
761 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
762 case ICMD_LDIVPOW2: /* val.i = constant */
764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
765 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
766 if (iptr->sx.val.i <= 15) {
767 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
768 M_CMOVGE(s1, s1, REG_ITMP2);
770 M_SRA_IMM(s1, 63, REG_ITMP2);
771 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
772 M_LADD(s1, REG_ITMP2, REG_ITMP2);
774 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
775 emit_store_dst(jd, iptr, d);
778 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
781 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
782 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
783 M_AND_IMM(s2, 0x1f, REG_ITMP3);
784 M_SLL(s1, REG_ITMP3, d);
785 M_IADD(d, REG_ZERO, d);
786 emit_store_dst(jd, iptr, d);
789 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
790 /* sx.val.i = constant */
792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
794 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
795 M_IADD(d, REG_ZERO, d);
796 emit_store_dst(jd, iptr, d);
799 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
802 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
804 M_AND_IMM(s2, 0x1f, REG_ITMP3);
805 M_SRA(s1, REG_ITMP3, d);
806 emit_store_dst(jd, iptr, d);
809 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
810 /* sx.val.i = constant */
812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
815 emit_store_dst(jd, iptr, d);
818 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
823 M_AND_IMM(s2, 0x1f, REG_ITMP2);
825 M_SRL(d, REG_ITMP2, d);
826 M_IADD(d, REG_ZERO, d);
827 emit_store_dst(jd, iptr, d);
830 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
831 /* sx.val.i = constant */
833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
834 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
836 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
837 M_IADD(d, REG_ZERO, d);
838 emit_store_dst(jd, iptr, d);
841 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
843 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
844 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
845 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
847 emit_store_dst(jd, iptr, d);
850 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
851 /* sx.val.i = constant */
853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
856 emit_store_dst(jd, iptr, d);
859 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
862 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
863 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
865 emit_store_dst(jd, iptr, d);
868 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
869 /* sx.val.i = constant */
871 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
872 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
873 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
874 emit_store_dst(jd, iptr, d);
877 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
880 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
881 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
883 emit_store_dst(jd, iptr, d);
886 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
887 /* sx.val.i = constant */
889 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
890 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
891 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
892 emit_store_dst(jd, iptr, d);
895 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
902 emit_store_dst(jd, iptr, d);
905 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
906 /* sx.val.i = constant */
908 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
910 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
911 M_AND_IMM(s1, iptr->sx.val.i, d);
912 } else if (iptr->sx.val.i == 0xffff) {
914 } else if (iptr->sx.val.i == 0xffffff) {
915 M_ZAPNOT_IMM(s1, 0x07, d);
917 ICONST(REG_ITMP2, iptr->sx.val.i);
918 M_AND(s1, REG_ITMP2, d);
920 emit_store_dst(jd, iptr, d);
923 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
924 /* sx.val.i = constant */
926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
927 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
929 M_MOV(s1, REG_ITMP1);
932 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
933 M_AND_IMM(s1, iptr->sx.val.i, d);
935 M_ISUB(REG_ZERO, s1, d);
936 M_AND_IMM(d, iptr->sx.val.i, d);
937 } else if (iptr->sx.val.i == 0xffff) {
940 M_ISUB(REG_ZERO, s1, d);
942 } else if (iptr->sx.val.i == 0xffffff) {
943 M_ZAPNOT_IMM(s1, 0x07, d);
945 M_ISUB(REG_ZERO, s1, d);
946 M_ZAPNOT_IMM(d, 0x07, d);
948 ICONST(REG_ITMP2, iptr->sx.val.i);
949 M_AND(s1, REG_ITMP2, d);
951 M_ISUB(REG_ZERO, s1, d);
952 M_AND(d, REG_ITMP2, d);
954 M_ISUB(REG_ZERO, d, d);
955 emit_store_dst(jd, iptr, d);
958 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
959 /* sx.val.l = constant */
961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
962 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
963 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
964 M_AND_IMM(s1, iptr->sx.val.l, d);
965 } else if (iptr->sx.val.l == 0xffffL) {
967 } else if (iptr->sx.val.l == 0xffffffL) {
968 M_ZAPNOT_IMM(s1, 0x07, d);
969 } else if (iptr->sx.val.l == 0xffffffffL) {
971 } else if (iptr->sx.val.l == 0xffffffffffL) {
972 M_ZAPNOT_IMM(s1, 0x1f, d);
973 } else if (iptr->sx.val.l == 0xffffffffffffL) {
974 M_ZAPNOT_IMM(s1, 0x3f, d);
975 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
976 M_ZAPNOT_IMM(s1, 0x7f, d);
978 LCONST(REG_ITMP2, iptr->sx.val.l);
979 M_AND(s1, REG_ITMP2, d);
981 emit_store_dst(jd, iptr, d);
984 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
985 /* sx.val.l = constant */
987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
988 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
990 M_MOV(s1, REG_ITMP1);
993 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
994 M_AND_IMM(s1, iptr->sx.val.l, d);
996 M_LSUB(REG_ZERO, s1, d);
997 M_AND_IMM(d, iptr->sx.val.l, d);
998 } else if (iptr->sx.val.l == 0xffffL) {
1001 M_LSUB(REG_ZERO, s1, d);
1003 } else if (iptr->sx.val.l == 0xffffffL) {
1004 M_ZAPNOT_IMM(s1, 0x07, d);
1006 M_LSUB(REG_ZERO, s1, d);
1007 M_ZAPNOT_IMM(d, 0x07, d);
1008 } else if (iptr->sx.val.l == 0xffffffffL) {
1011 M_LSUB(REG_ZERO, s1, d);
1013 } else if (iptr->sx.val.l == 0xffffffffffL) {
1014 M_ZAPNOT_IMM(s1, 0x1f, d);
1016 M_LSUB(REG_ZERO, s1, d);
1017 M_ZAPNOT_IMM(d, 0x1f, d);
1018 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1019 M_ZAPNOT_IMM(s1, 0x3f, d);
1021 M_LSUB(REG_ZERO, s1, d);
1022 M_ZAPNOT_IMM(d, 0x3f, d);
1023 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1024 M_ZAPNOT_IMM(s1, 0x7f, d);
1026 M_LSUB(REG_ZERO, s1, d);
1027 M_ZAPNOT_IMM(d, 0x7f, d);
1029 LCONST(REG_ITMP2, iptr->sx.val.l);
1030 M_AND(s1, REG_ITMP2, d);
1032 M_LSUB(REG_ZERO, s1, d);
1033 M_AND(d, REG_ITMP2, d);
1035 M_LSUB(REG_ZERO, d, d);
1036 emit_store_dst(jd, iptr, d);
1039 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1042 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1043 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1044 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1046 emit_store_dst(jd, iptr, d);
1049 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1050 /* sx.val.i = constant */
1052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1054 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1055 M_OR_IMM(s1, iptr->sx.val.i, d);
1057 ICONST(REG_ITMP2, iptr->sx.val.i);
1058 M_OR(s1, REG_ITMP2, d);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1064 /* sx.val.l = constant */
1066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1068 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1069 M_OR_IMM(s1, iptr->sx.val.l, d);
1071 LCONST(REG_ITMP2, iptr->sx.val.l);
1072 M_OR(s1, REG_ITMP2, d);
1074 emit_store_dst(jd, iptr, d);
1077 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1081 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1082 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1088 /* sx.val.i = constant */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1092 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1093 M_XOR_IMM(s1, iptr->sx.val.i, d);
1095 ICONST(REG_ITMP2, iptr->sx.val.i);
1096 M_XOR(s1, REG_ITMP2, d);
1098 emit_store_dst(jd, iptr, d);
1101 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1102 /* sx.val.l = constant */
1104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1105 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1106 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1107 M_XOR_IMM(s1, iptr->sx.val.l, d);
1109 LCONST(REG_ITMP2, iptr->sx.val.l);
1110 M_XOR(s1, REG_ITMP2, d);
1112 emit_store_dst(jd, iptr, d);
1116 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1118 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1119 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1120 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1121 M_CMPLT(s1, s2, REG_ITMP3);
1122 M_CMPLT(s2, s1, REG_ITMP1);
1123 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1124 emit_store_dst(jd, iptr, d);
1128 /* floating operations ************************************************/
1130 case ICMD_FNEG: /* ..., value ==> ..., - value */
1132 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1133 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_DNEG: /* ..., value ==> ..., - value */
1140 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1141 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1143 emit_store_dst(jd, iptr, d);
1146 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1148 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1149 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1150 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1154 if (d == s1 || d == s2) {
1155 M_FADDS(s1, s2, REG_FTMP3);
1157 M_FMOV(REG_FTMP3, d);
1163 emit_store_dst(jd, iptr, d);
1166 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1168 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1169 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1170 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1174 if (d == s1 || d == s2) {
1175 M_DADDS(s1, s2, REG_FTMP3);
1177 M_FMOV(REG_FTMP3, d);
1183 emit_store_dst(jd, iptr, d);
1186 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1188 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1189 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1190 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1194 if (d == s1 || d == s2) {
1195 M_FSUBS(s1, s2, REG_FTMP3);
1197 M_FMOV(REG_FTMP3, d);
1203 emit_store_dst(jd, iptr, d);
1206 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1208 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1209 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1210 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1214 if (d == s1 || d == s2) {
1215 M_DSUBS(s1, s2, REG_FTMP3);
1217 M_FMOV(REG_FTMP3, d);
1223 emit_store_dst(jd, iptr, d);
1226 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1228 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1229 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1230 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1234 if (d == s1 || d == s2) {
1235 M_FMULS(s1, s2, REG_FTMP3);
1237 M_FMOV(REG_FTMP3, d);
1243 emit_store_dst(jd, iptr, d);
1246 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1248 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1249 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1250 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1254 if (d == s1 || d == s2) {
1255 M_DMULS(s1, s2, REG_FTMP3);
1257 M_FMOV(REG_FTMP3, d);
1263 emit_store_dst(jd, iptr, d);
1266 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1268 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1269 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1270 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1274 if (d == s1 || d == s2) {
1275 M_FDIVS(s1, s2, REG_FTMP3);
1277 M_FMOV(REG_FTMP3, d);
1283 emit_store_dst(jd, iptr, d);
1286 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1288 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1289 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1290 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1294 if (d == s1 || d == s2) {
1295 M_DDIVS(s1, s2, REG_FTMP3);
1297 M_FMOV(REG_FTMP3, d);
1303 emit_store_dst(jd, iptr, d);
1306 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1309 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1310 disp = dseg_add_unique_double(cd, 0.0);
1311 M_LST(s1, REG_PV, disp);
1312 M_DLD(d, REG_PV, disp);
1314 emit_store_dst(jd, iptr, d);
1317 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1321 disp = dseg_add_unique_double(cd, 0.0);
1322 M_LST(s1, REG_PV, disp);
1323 M_DLD(d, REG_PV, disp);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_F2I: /* ..., value ==> ..., (int) 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_CVTLI(REG_FTMP2, REG_FTMP3);
1335 M_DST(REG_FTMP3, REG_PV, disp);
1336 M_ILD(d, REG_PV, disp);
1337 emit_store_dst(jd, iptr, d);
1340 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1342 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1343 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1344 disp = dseg_add_unique_double(cd, 0.0);
1345 M_CVTDL_C(s1, REG_FTMP2);
1346 M_DST(REG_FTMP2, REG_PV, disp);
1347 M_LLD(d, REG_PV, disp);
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1353 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1354 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1357 emit_store_dst(jd, iptr, d);
1360 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1362 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1363 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1375 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1376 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1377 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1379 M_LSUB_IMM(REG_ZERO, 1, d);
1380 M_FCMPEQ(s1, s2, REG_FTMP3);
1381 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1383 M_FCMPLT(s2, s1, REG_FTMP3);
1384 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1385 M_LADD_IMM(REG_ZERO, 1, d);
1387 M_LSUB_IMM(REG_ZERO, 1, d);
1388 M_FCMPEQS(s1, s2, REG_FTMP3);
1390 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1392 M_FCMPLTS(s2, s1, REG_FTMP3);
1394 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1395 M_LADD_IMM(REG_ZERO, 1, d);
1397 emit_store_dst(jd, iptr, d);
1400 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1402 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1403 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1404 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1406 M_LADD_IMM(REG_ZERO, 1, d);
1407 M_FCMPEQ(s1, s2, REG_FTMP3);
1408 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1410 M_FCMPLT(s1, s2, REG_FTMP3);
1411 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1412 M_LSUB_IMM(REG_ZERO, 1, d);
1414 M_LADD_IMM(REG_ZERO, 1, d);
1415 M_FCMPEQS(s1, s2, REG_FTMP3);
1417 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1419 M_FCMPLTS(s1, s2, REG_FTMP3);
1421 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1422 M_LSUB_IMM(REG_ZERO, 1, d);
1424 emit_store_dst(jd, iptr, d);
1428 /* memory operations **************************************************/
1430 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1434 emit_nullpointer_check(cd, s1);
1435 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1436 emit_store_dst(jd, iptr, d);
1439 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1442 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1443 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1444 emit_array_checks(cd, iptr, s1, s2);
1445 if (has_ext_instr_set) {
1446 M_LADD(s2, s1, REG_ITMP1);
1447 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1451 M_LADD(s2, s1, REG_ITMP1);
1452 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1453 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1454 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1455 M_SRA_IMM(d, 56, d);
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1465 emit_array_checks(cd, iptr, s1, s2);
1466 if (has_ext_instr_set) {
1467 M_LADD(s2, s1, REG_ITMP1);
1468 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1469 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1472 M_LADD (s2, s1, REG_ITMP1);
1473 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1474 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1475 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1476 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1478 emit_store_dst(jd, iptr, d);
1481 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1484 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1485 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1486 emit_array_checks(cd, iptr, s1, s2);
1487 if (has_ext_instr_set) {
1488 M_LADD(s2, s1, REG_ITMP1);
1489 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1490 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1493 M_LADD(s2, s1, REG_ITMP1);
1494 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1495 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1496 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1497 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1498 M_SRA_IMM(d, 48, d);
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1507 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1508 emit_array_checks(cd, iptr, s1, s2);
1509 M_S4ADDQ(s2, s1, REG_ITMP1);
1510 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1511 emit_store_dst(jd, iptr, d);
1514 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1517 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1519 emit_array_checks(cd, iptr, s1, s2);
1520 M_S8ADDQ(s2, s1, REG_ITMP1);
1521 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1522 emit_store_dst(jd, iptr, d);
1525 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1528 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1529 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1530 emit_array_checks(cd, iptr, s1, s2);
1531 M_S4ADDQ(s2, s1, REG_ITMP1);
1532 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1533 emit_store_dst(jd, iptr, d);
1536 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1539 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1540 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1541 emit_array_checks(cd, iptr, s1, s2);
1542 M_S8ADDQ(s2, s1, REG_ITMP1);
1543 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1544 emit_store_dst(jd, iptr, d);
1547 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1549 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1550 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1552 emit_array_checks(cd, iptr, s1, s2);
1553 M_SAADDQ(s2, s1, REG_ITMP1);
1554 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1555 emit_store_dst(jd, iptr, d);
1559 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1563 emit_array_checks(cd, iptr, s1, s2);
1564 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1565 if (has_ext_instr_set) {
1566 M_LADD(s2, s1, REG_ITMP1);
1567 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1570 M_LADD(s2, s1, REG_ITMP1);
1571 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1572 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1573 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1574 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1575 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1576 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1580 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1582 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1583 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1584 emit_array_checks(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, 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, data[0]));
1595 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, 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 emit_array_checks(cd, iptr, s1, s2);
1608 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1609 if (has_ext_instr_set) {
1610 M_LADD(s2, s1, REG_ITMP1);
1611 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1612 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1615 M_LADD(s2, s1, REG_ITMP1);
1616 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1617 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1618 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1619 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1620 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1621 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1622 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1626 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1628 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1629 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1630 emit_array_checks(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 emit_array_checks(cd, iptr, s1, s2);
1641 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1642 M_S8ADDQ(s2, s1, REG_ITMP1);
1643 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1646 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1649 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1650 emit_array_checks(cd, iptr, s1, s2);
1651 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1652 M_S4ADDQ(s2, s1, REG_ITMP1);
1653 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1656 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1658 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1659 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1660 emit_array_checks(cd, iptr, s1, s2);
1661 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1662 M_S8ADDQ(s2, s1, REG_ITMP1);
1663 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1666 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1668 s1 = emit_load_s1(jd, iptr, REG_A0);
1669 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1670 emit_array_checks(cd, iptr, s1, s2);
1671 s3 = emit_load_s3(jd, iptr, REG_A1);
1673 M_INTMOVE(s1, REG_A0);
1674 M_INTMOVE(s3, REG_A1);
1676 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1677 M_ALD(REG_PV, REG_PV, disp);
1678 M_JSR(REG_RA, REG_PV);
1679 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1680 M_LDA(REG_PV, REG_RA, -disp);
1682 M_BEQZ(REG_RESULT, 0);
1683 codegen_add_arraystoreexception_ref(cd);
1685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1687 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1688 M_SAADDQ(s2, s1, REG_ITMP1);
1689 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1693 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 emit_array_checks(cd, iptr, s1, s2);
1698 if (has_ext_instr_set) {
1699 M_LADD(s2, s1, REG_ITMP1);
1700 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1703 M_LADD(s2, s1, REG_ITMP1);
1704 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1705 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1706 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1707 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1708 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1709 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1713 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1715 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1716 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1717 emit_array_checks(cd, iptr, s1, s2);
1718 if (has_ext_instr_set) {
1719 M_LADD(s2, s1, REG_ITMP1);
1720 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1721 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1724 M_LADD(s2, s1, REG_ITMP1);
1725 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1726 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1727 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1728 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1729 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1730 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1731 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1735 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1738 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1739 emit_array_checks(cd, iptr, s1, s2);
1740 if (has_ext_instr_set) {
1741 M_LADD(s2, s1, REG_ITMP1);
1742 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1743 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1746 M_LADD(s2, s1, REG_ITMP1);
1747 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1748 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1749 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1750 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1751 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1752 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1753 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1757 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1759 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1760 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1761 emit_array_checks(cd, iptr, s1, s2);
1762 M_S4ADDQ(s2, s1, REG_ITMP1);
1763 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1766 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1770 emit_array_checks(cd, iptr, s1, s2);
1771 M_S8ADDQ(s2, s1, REG_ITMP1);
1772 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1775 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1778 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1779 emit_array_checks(cd, iptr, s1, s2);
1780 M_SAADDQ(s2, s1, REG_ITMP1);
1781 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1785 case ICMD_GETSTATIC: /* ... ==> ..., value */
1787 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1788 uf = iptr->sx.s23.s3.uf;
1789 fieldtype = uf->fieldref->parseddesc.fd->type;
1790 disp = dseg_add_unique_address(cd, uf);
1792 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1795 fi = iptr->sx.s23.s3.fmiref->p.field;
1796 fieldtype = fi->type;
1797 disp = dseg_add_address(cd, &(fi->value));
1799 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1800 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1804 M_ALD(REG_ITMP1, REG_PV, disp);
1805 switch (fieldtype) {
1807 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1808 M_ILD(d, REG_ITMP1, 0);
1811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1812 M_LLD(d, REG_ITMP1, 0);
1815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1816 M_ALD(d, REG_ITMP1, 0);
1819 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1820 M_FLD(d, REG_ITMP1, 0);
1823 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1824 M_DLD(d, REG_ITMP1, 0);
1827 emit_store_dst(jd, iptr, d);
1830 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1832 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1833 uf = iptr->sx.s23.s3.uf;
1834 fieldtype = uf->fieldref->parseddesc.fd->type;
1835 disp = dseg_add_unique_address(cd, uf);
1837 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1840 fi = iptr->sx.s23.s3.fmiref->p.field;
1841 fieldtype = fi->type;
1842 disp = dseg_add_address(cd, &(fi->value));
1844 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1845 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1849 M_ALD(REG_ITMP1, REG_PV, disp);
1850 switch (fieldtype) {
1852 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1853 M_IST(s1, REG_ITMP1, 0);
1856 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1857 M_LST(s1, REG_ITMP1, 0);
1860 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1861 M_AST(s1, REG_ITMP1, 0);
1864 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1865 M_FST(s1, REG_ITMP1, 0);
1868 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1869 M_DST(s1, REG_ITMP1, 0);
1874 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1875 /* val = value (in current instruction) */
1876 /* following NOP) */
1878 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1879 uf = iptr->sx.s23.s3.uf;
1880 fieldtype = uf->fieldref->parseddesc.fd->type;
1881 disp = dseg_add_unique_address(cd, uf);
1883 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1886 fi = iptr->sx.s23.s3.fmiref->p.field;
1887 fieldtype = fi->type;
1888 disp = dseg_add_address(cd, &(fi->value));
1890 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1891 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1895 M_ALD(REG_ITMP1, REG_PV, disp);
1896 switch (fieldtype) {
1898 M_IST(REG_ZERO, REG_ITMP1, 0);
1901 M_LST(REG_ZERO, REG_ITMP1, 0);
1904 M_AST(REG_ZERO, REG_ITMP1, 0);
1907 M_FST(REG_ZERO, REG_ITMP1, 0);
1910 M_DST(REG_ZERO, REG_ITMP1, 0);
1916 case ICMD_GETFIELD: /* ... ==> ..., value */
1918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1919 emit_nullpointer_check(cd, s1);
1921 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1922 uf = iptr->sx.s23.s3.uf;
1923 fieldtype = uf->fieldref->parseddesc.fd->type;
1926 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1929 fi = iptr->sx.s23.s3.fmiref->p.field;
1930 fieldtype = fi->type;
1934 switch (fieldtype) {
1936 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1940 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1948 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1952 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1956 emit_store_dst(jd, iptr, d);
1959 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1962 emit_nullpointer_check(cd, s1);
1964 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1965 uf = iptr->sx.s23.s3.uf;
1966 fieldtype = uf->fieldref->parseddesc.fd->type;
1971 fi = iptr->sx.s23.s3.fmiref->p.field;
1972 fieldtype = fi->type;
1976 if (IS_INT_LNG_TYPE(fieldtype))
1977 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1979 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1981 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1982 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1984 switch (fieldtype) {
1986 M_IST(s2, s1, disp);
1989 M_LST(s2, s1, disp);
1992 M_AST(s2, s1, disp);
1995 M_FST(s2, s1, disp);
1998 M_DST(s2, s1, disp);
2003 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2004 /* val = value (in current instruction) */
2005 /* following NOP) */
2007 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2008 emit_nullpointer_check(cd, s1);
2010 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2011 uf = iptr->sx.s23.s3.uf;
2012 fieldtype = uf->fieldref->parseddesc.fd->type;
2015 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2018 fi = iptr->sx.s23.s3.fmiref->p.field;
2019 fieldtype = fi->type;
2023 switch (fieldtype) {
2025 M_IST(REG_ZERO, s1, disp);
2028 M_LST(REG_ZERO, s1, disp);
2031 M_AST(REG_ZERO, s1, disp);
2034 M_FST(REG_ZERO, s1, disp);
2037 M_DST(REG_ZERO, s1, disp);
2043 /* branch operations **************************************************/
2045 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2048 M_INTMOVE(s1, REG_ITMP1_XPTR);
2050 #ifdef ENABLE_VERIFIER
2051 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2052 unresolved_class *uc = iptr->sx.s23.s2.uc;
2054 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2056 #endif /* ENABLE_VERIFIER */
2058 disp = dseg_add_functionptr(cd, asm_handle_exception);
2059 M_ALD(REG_ITMP2, REG_PV, disp);
2060 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2061 M_NOP; /* nop ensures that XPC is less than the end */
2062 /* of basic block */
2066 case ICMD_GOTO: /* ... ==> ... */
2067 case ICMD_RET: /* ... ==> ... */
2070 codegen_add_branch_ref(cd, iptr->dst.block);
2074 case ICMD_JSR: /* ... ==> ... */
2077 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2081 case ICMD_IFNULL: /* ..., value ==> ... */
2083 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2085 codegen_add_branch_ref(cd, iptr->dst.block);
2088 case ICMD_IFNONNULL: /* ..., value ==> ... */
2090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2092 codegen_add_branch_ref(cd, iptr->dst.block);
2095 case ICMD_IFEQ: /* ..., value ==> ... */
2097 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2098 if (iptr->sx.val.i == 0) {
2102 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2103 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2106 ICONST(REG_ITMP2, iptr->sx.val.i);
2107 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2109 M_BNEZ(REG_ITMP1, 0);
2111 codegen_add_branch_ref(cd, iptr->dst.block);
2114 case ICMD_IFLT: /* ..., value ==> ... */
2116 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2117 if (iptr->sx.val.i == 0) {
2121 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2122 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2125 ICONST(REG_ITMP2, iptr->sx.val.i);
2126 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2128 M_BNEZ(REG_ITMP1, 0);
2130 codegen_add_branch_ref(cd, iptr->dst.block);
2133 case ICMD_IFLE: /* ..., value ==> ... */
2135 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2136 if (iptr->sx.val.i == 0) {
2140 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2141 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2144 ICONST(REG_ITMP2, iptr->sx.val.i);
2145 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2147 M_BNEZ(REG_ITMP1, 0);
2149 codegen_add_branch_ref(cd, iptr->dst.block);
2152 case ICMD_IFNE: /* ..., value ==> ... */
2154 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2155 if (iptr->sx.val.i == 0) {
2159 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2160 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2163 ICONST(REG_ITMP2, iptr->sx.val.i);
2164 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2166 M_BEQZ(REG_ITMP1, 0);
2168 codegen_add_branch_ref(cd, iptr->dst.block);
2171 case ICMD_IFGT: /* ..., value ==> ... */
2173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2174 if (iptr->sx.val.i == 0) {
2178 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2179 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2182 ICONST(REG_ITMP2, iptr->sx.val.i);
2183 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2185 M_BEQZ(REG_ITMP1, 0);
2187 codegen_add_branch_ref(cd, iptr->dst.block);
2190 case ICMD_IFGE: /* ..., value ==> ... */
2192 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2193 if (iptr->sx.val.i == 0) {
2197 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2198 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2201 ICONST(REG_ITMP2, iptr->sx.val.i);
2202 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2204 M_BEQZ(REG_ITMP1, 0);
2206 codegen_add_branch_ref(cd, iptr->dst.block);
2209 case ICMD_IF_LEQ: /* ..., value ==> ... */
2211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2212 if (iptr->sx.val.l == 0) {
2216 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2217 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2220 LCONST(REG_ITMP2, iptr->sx.val.l);
2221 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2223 M_BNEZ(REG_ITMP1, 0);
2225 codegen_add_branch_ref(cd, iptr->dst.block);
2228 case ICMD_IF_LLT: /* ..., value ==> ... */
2230 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2231 if (iptr->sx.val.l == 0) {
2235 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2236 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2239 LCONST(REG_ITMP2, iptr->sx.val.l);
2240 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2242 M_BNEZ(REG_ITMP1, 0);
2244 codegen_add_branch_ref(cd, iptr->dst.block);
2247 case ICMD_IF_LLE: /* ..., value ==> ... */
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250 if (iptr->sx.val.l == 0) {
2254 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2255 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2258 LCONST(REG_ITMP2, iptr->sx.val.l);
2259 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2261 M_BNEZ(REG_ITMP1, 0);
2263 codegen_add_branch_ref(cd, iptr->dst.block);
2266 case ICMD_IF_LNE: /* ..., value ==> ... */
2268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269 if (iptr->sx.val.l == 0) {
2273 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2274 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2277 LCONST(REG_ITMP2, iptr->sx.val.l);
2278 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2280 M_BEQZ(REG_ITMP1, 0);
2282 codegen_add_branch_ref(cd, iptr->dst.block);
2285 case ICMD_IF_LGT: /* ..., value ==> ... */
2287 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2288 if (iptr->sx.val.l == 0) {
2292 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2293 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2296 LCONST(REG_ITMP2, iptr->sx.val.l);
2297 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2299 M_BEQZ(REG_ITMP1, 0);
2301 codegen_add_branch_ref(cd, iptr->dst.block);
2304 case ICMD_IF_LGE: /* ..., value ==> ... */
2306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2307 if (iptr->sx.val.l == 0) {
2311 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2312 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2315 LCONST(REG_ITMP2, iptr->sx.val.l);
2316 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2318 M_BEQZ(REG_ITMP1, 0);
2320 codegen_add_branch_ref(cd, iptr->dst.block);
2323 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2324 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2325 case ICMD_IF_ACMPEQ:
2327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2328 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2329 M_CMPEQ(s1, s2, REG_ITMP1);
2330 M_BNEZ(REG_ITMP1, 0);
2331 codegen_add_branch_ref(cd, iptr->dst.block);
2334 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2335 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2336 case ICMD_IF_ACMPNE:
2338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2340 M_CMPEQ(s1, s2, REG_ITMP1);
2341 M_BEQZ(REG_ITMP1, 0);
2342 codegen_add_branch_ref(cd, iptr->dst.block);
2345 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2346 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2348 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2349 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2350 M_CMPLT(s1, s2, REG_ITMP1);
2351 M_BNEZ(REG_ITMP1, 0);
2352 codegen_add_branch_ref(cd, iptr->dst.block);
2355 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2356 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2358 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2359 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2360 M_CMPLE(s1, s2, REG_ITMP1);
2361 M_BEQZ(REG_ITMP1, 0);
2362 codegen_add_branch_ref(cd, iptr->dst.block);
2365 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2366 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2369 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2370 M_CMPLE(s1, s2, REG_ITMP1);
2371 M_BNEZ(REG_ITMP1, 0);
2372 codegen_add_branch_ref(cd, iptr->dst.block);
2375 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2376 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2378 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2379 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2380 M_CMPLT(s1, s2, REG_ITMP1);
2381 M_BEQZ(REG_ITMP1, 0);
2382 codegen_add_branch_ref(cd, iptr->dst.block);
2386 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2389 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2390 M_INTMOVE(s1, REG_RESULT);
2391 goto nowperformreturn;
2393 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2395 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2396 M_INTMOVE(s1, REG_RESULT);
2398 #ifdef ENABLE_VERIFIER
2399 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2400 unresolved_class *uc = iptr->sx.s23.s2.uc;
2402 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2404 #endif /* ENABLE_VERIFIER */
2405 goto nowperformreturn;
2407 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2410 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2411 M_FLTMOVE(s1, REG_FRESULT);
2412 goto nowperformreturn;
2414 case ICMD_RETURN: /* ... ==> ... */
2420 p = cd->stackframesize;
2422 /* call trace function */
2424 #if !defined(NDEBUG)
2425 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2426 emit_verbosecall_exit(jd);
2429 #if defined(ENABLE_THREADS)
2430 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2431 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2433 switch (iptr->opc) {
2437 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2441 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2445 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2446 M_ALD(REG_PV, REG_PV, disp);
2447 M_JSR(REG_RA, REG_PV);
2448 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2449 M_LDA(REG_PV, REG_RA, disp);
2451 switch (iptr->opc) {
2455 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2459 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2465 /* restore return address */
2467 if (!jd->isleafmethod) {
2468 p--; M_LLD(REG_RA, REG_SP, p * 8);
2471 /* restore saved registers */
2473 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2474 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2476 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2477 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2480 /* deallocate stack */
2482 if (cd->stackframesize)
2483 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2485 M_RET(REG_ZERO, REG_RA);
2491 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2494 branch_target_t *table;
2496 table = iptr->dst.table;
2498 l = iptr->sx.s23.s2.tablelow;
2499 i = iptr->sx.s23.s3.tablehigh;
2501 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2503 M_INTMOVE(s1, REG_ITMP1);
2504 } else if (l <= 32768) {
2505 M_LDA(REG_ITMP1, s1, -l);
2507 ICONST(REG_ITMP2, l);
2508 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2511 /* number of targets */
2517 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2519 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2520 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2522 M_BEQZ(REG_ITMP2, 0);
2523 codegen_add_branch_ref(cd, table[0].block);
2525 /* build jump table top down and use address of lowest entry */
2530 dseg_add_target(cd, table->block);
2535 /* length of dataseg after last dseg_add_target is used by load */
2537 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2538 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2539 M_JMP(REG_ZERO, REG_ITMP2);
2544 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2547 lookup_target_t *lookup;
2549 lookup = iptr->dst.lookup;
2551 i = iptr->sx.s23.s2.lookupcount;
2553 MCODECHECK((i<<2)+8);
2554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2557 val = lookup->value;
2558 if ((val >= 0) && (val <= 255)) {
2559 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2561 if ((val >= -32768) && (val <= 32767)) {
2562 M_LDA(REG_ITMP2, REG_ZERO, val);
2564 disp = dseg_add_s4(cd, val);
2565 M_ILD(REG_ITMP2, REG_PV, disp);
2567 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2569 M_BNEZ(REG_ITMP2, 0);
2570 codegen_add_branch_ref(cd, lookup->target.block);
2576 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2583 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2585 bte = iptr->sx.s23.s3.bte;
2589 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2591 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2592 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2593 case ICMD_INVOKEINTERFACE:
2595 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2597 um = iptr->sx.s23.s3.um;
2598 md = um->methodref->parseddesc.md;
2601 lm = iptr->sx.s23.s3.fmiref->p.method;
2603 md = lm->parseddesc;
2607 s3 = md->paramcount;
2609 MCODECHECK((s3 << 1) + 64);
2611 /* copy arguments to registers or stack location */
2613 for (s3 = s3 - 1; s3 >= 0; s3--) {
2614 var = VAR(iptr->sx.s23.s2.args[s3]);
2616 /* Already Preallocated (ARGVAR) ? */
2617 if (var->flags & PREALLOC)
2620 if (IS_INT_LNG_TYPE(var->type)) {
2621 if (!md->params[s3].inmemory) {
2622 s1 = rd->argintregs[md->params[s3].regoff];
2623 d = emit_load(jd, iptr, var, s1);
2627 d = emit_load(jd, iptr, var, REG_ITMP1);
2628 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2632 if (!md->params[s3].inmemory) {
2633 s1 = rd->argfltregs[md->params[s3].regoff];
2634 d = emit_load(jd, iptr, var, s1);
2638 d = emit_load(jd, iptr, var, REG_FTMP1);
2639 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2644 switch (iptr->opc) {
2646 disp = dseg_add_functionptr(cd, bte->fp);
2648 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2651 case ICMD_INVOKESPECIAL:
2653 codegen_add_nullpointerexception_ref(cd);
2656 case ICMD_INVOKESTATIC:
2658 disp = dseg_add_unique_address(cd, um);
2660 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2664 disp = dseg_add_address(cd, lm->stubroutine);
2666 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2669 case ICMD_INVOKEVIRTUAL:
2670 emit_nullpointer_check(cd, REG_A0);
2673 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2678 s1 = OFFSET(vftbl_t, table[0]) +
2679 sizeof(methodptr) * lm->vftblindex;
2681 M_ALD(REG_METHODPTR, REG_A0,
2682 OFFSET(java_objectheader, vftbl));
2683 M_ALD(REG_PV, REG_METHODPTR, s1);
2686 case ICMD_INVOKEINTERFACE:
2687 emit_nullpointer_check(cd, REG_A0);
2690 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2696 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2697 sizeof(methodptr*) * lm->class->index;
2699 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2702 M_ALD(REG_METHODPTR, REG_A0,
2703 OFFSET(java_objectheader, vftbl));
2704 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2705 M_ALD(REG_PV, REG_METHODPTR, s2);
2709 /* generate the actual call */
2711 M_JSR(REG_RA, REG_PV);
2712 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2713 M_LDA(REG_PV, REG_RA, -disp);
2715 /* actually only used for ICMD_BUILTIN */
2717 if (INSTRUCTION_MUST_CHECK(iptr)) {
2718 M_BEQZ(REG_RESULT, 0);
2719 codegen_add_fillinstacktrace_ref(cd);
2722 /* store the return value */
2724 d = md->returntype.type;
2726 if (d != TYPE_VOID) {
2727 if (IS_INT_LNG_TYPE(d)) {
2728 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2729 M_INTMOVE(REG_RESULT, s1);
2732 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2733 M_FLTMOVE(REG_FRESULT, s1);
2735 emit_store_dst(jd, iptr, s1);
2740 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2742 /* val.a: (classinfo*) superclass */
2744 /* superclass is an interface:
2746 * OK if ((sub == NULL) ||
2747 * (sub->vftbl->interfacetablelength > super->index) &&
2748 * (sub->vftbl->interfacetable[-super->index] != NULL));
2750 * superclass is a class:
2752 * OK if ((sub == NULL) || (0
2753 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2754 * super->vftbl->diffval));
2757 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2758 /* object type cast-check */
2761 vftbl_t *supervftbl;
2764 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2770 super = iptr->sx.s23.s3.c.cls;
2771 superindex = super->index;
2772 supervftbl = super->vftbl;
2775 #if defined(ENABLE_THREADS)
2776 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2780 /* calculate interface checkcast code size */
2784 s2 += opt_shownops ? 1 : 0;
2786 /* calculate class checkcast code size */
2788 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
2790 s3 += opt_shownops ? 1 : 0;
2792 /* if class is not resolved, check which code to call */
2794 if (super == NULL) {
2795 M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
2797 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2799 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2800 iptr->sx.s23.s3.c.ref,
2803 M_ILD(REG_ITMP2, REG_PV, disp);
2804 disp = dseg_add_s4(cd, ACC_INTERFACE);
2805 M_ILD(REG_ITMP3, REG_PV, disp);
2806 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2807 M_BEQZ(REG_ITMP2, s2 + 1);
2810 /* interface checkcast code */
2812 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2813 if (super == NULL) {
2814 codegen_add_patch_ref(cd,
2815 PATCHER_checkcast_instanceof_interface,
2816 iptr->sx.s23.s3.c.ref,
2822 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2823 M_ILD(REG_ITMP3, REG_ITMP2,
2824 OFFSET(vftbl_t, interfacetablelength));
2825 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2826 M_BLEZ(REG_ITMP3, 0);
2827 codegen_add_classcastexception_ref(cd, s1);
2828 M_ALD(REG_ITMP3, REG_ITMP2,
2829 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2830 superindex * sizeof(methodptr*)));
2831 M_BEQZ(REG_ITMP3, 0);
2832 codegen_add_classcastexception_ref(cd, s1);
2838 /* class checkcast code */
2840 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2841 if (super == NULL) {
2842 disp = dseg_add_unique_address(cd, NULL);
2844 codegen_add_patch_ref(cd,
2845 PATCHER_resolve_classref_to_vftbl,
2846 iptr->sx.s23.s3.c.ref,
2850 disp = dseg_add_address(cd, supervftbl);
2855 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2856 M_ALD(REG_ITMP3, REG_PV, disp);
2857 #if defined(ENABLE_THREADS)
2858 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2860 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2861 /* if (s1 != REG_ITMP1) { */
2862 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2863 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2864 /* #if defined(ENABLE_THREADS) */
2865 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2867 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2870 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2871 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2872 M_ALD(REG_ITMP3, REG_PV, disp);
2873 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2874 #if defined(ENABLE_THREADS)
2875 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2878 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2879 M_BEQZ(REG_ITMP3, 0);
2880 codegen_add_classcastexception_ref(cd, s1);
2883 d = codegen_reg_of_dst(jd, iptr, s1);
2886 /* array type cast-check */
2888 s1 = emit_load_s1(jd, iptr, REG_A0);
2889 M_INTMOVE(s1, REG_A0);
2891 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
2893 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2894 codegen_add_patch_ref(cd,
2895 PATCHER_resolve_classref_to_classinfo,
2896 iptr->sx.s23.s3.c.ref,
2900 M_ALD(REG_A1, REG_PV, disp);
2901 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
2902 M_ALD(REG_PV, REG_PV, disp);
2903 M_JSR(REG_RA, REG_PV);
2904 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2905 M_LDA(REG_PV, REG_RA, -disp);
2907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2908 M_BEQZ(REG_RESULT, 0);
2909 codegen_add_classcastexception_ref(cd, s1);
2911 d = codegen_reg_of_dst(jd, iptr, s1);
2915 emit_store_dst(jd, iptr, d);
2918 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2920 /* val.a: (classinfo*) superclass */
2922 /* superclass is an interface:
2924 * return (sub != NULL) &&
2925 * (sub->vftbl->interfacetablelength > super->index) &&
2926 * (sub->vftbl->interfacetable[-super->index] != NULL);
2928 * superclass is a class:
2930 * return ((sub != NULL) && (0
2931 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2932 * super->vftbl->diffvall));
2937 vftbl_t *supervftbl;
2940 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2946 super = iptr->sx.s23.s3.c.cls;
2947 superindex = super->index;
2948 supervftbl = super->vftbl;
2951 #if defined(ENABLE_THREADS)
2952 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2955 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2957 M_MOV(s1, REG_ITMP1);
2961 /* calculate interface instanceof code size */
2965 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_shownops ? 1 : 0);
2967 /* calculate class instanceof code size */
2971 s3 += (opt_shownops ? 1 : 0);
2973 /* if class is not resolved, check which code to call */
2975 if (super == NULL) {
2977 M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
2979 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2981 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2982 iptr->sx.s23.s3.c.ref, disp);
2984 M_ILD(REG_ITMP3, REG_PV, disp);
2986 disp = dseg_add_s4(cd, ACC_INTERFACE);
2987 M_ILD(REG_ITMP2, REG_PV, disp);
2988 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
2989 M_BEQZ(REG_ITMP3, s2 + 1);
2992 /* interface instanceof code */
2994 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2995 if (super == NULL) {
2996 /* If d == REG_ITMP2, then it's destroyed in check
3001 codegen_add_patch_ref(cd,
3002 PATCHER_checkcast_instanceof_interface,
3003 iptr->sx.s23.s3.c.ref, 0);
3010 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3011 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3012 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3013 M_BLEZ(REG_ITMP3, 2);
3014 M_ALD(REG_ITMP1, REG_ITMP1,
3015 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3016 superindex * sizeof(methodptr*)));
3017 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3023 /* class instanceof code */
3025 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3026 if (super == NULL) {
3027 disp = dseg_add_unique_address(cd, NULL);
3029 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3030 iptr->sx.s23.s3.c.ref,
3034 disp = dseg_add_address(cd, supervftbl);
3040 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3041 M_ALD(REG_ITMP2, REG_PV, disp);
3042 #if defined(ENABLE_THREADS)
3043 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3045 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3046 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3047 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3048 #if defined(ENABLE_THREADS)
3049 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3051 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3052 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3054 emit_store_dst(jd, iptr, d);
3058 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3060 /* check for negative sizes and copy sizes to stack if necessary */
3062 MCODECHECK((iptr->s1.argcount << 1) + 64);
3064 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3066 var = VAR(iptr->sx.s23.s2.args[s1]);
3068 /* copy SAVEDVAR sizes to stack */
3070 /* Already Preallocated? */
3072 if (!(var->flags & PREALLOC)) {
3073 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3074 M_LST(s2, REG_SP, s1 * 8);
3078 /* a0 = dimension count */
3080 ICONST(REG_A0, iptr->s1.argcount);
3082 /* is patcher function set? */
3084 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3085 disp = dseg_add_unique_address(cd, 0);
3087 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
3088 iptr->sx.s23.s3.c.ref,
3092 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3094 /* a1 = arraydescriptor */
3096 M_ALD(REG_A1, REG_PV, disp);
3098 /* a2 = pointer to dimensions = stack pointer */
3100 M_INTMOVE(REG_SP, REG_A2);
3102 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3103 M_ALD(REG_PV, REG_PV, disp);
3104 M_JSR(REG_RA, REG_PV);
3105 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3106 M_LDA(REG_PV, REG_RA, -disp);
3108 /* check for exception before result assignment */
3110 M_BEQZ(REG_RESULT, 0);
3111 codegen_add_fillinstacktrace_ref(cd);
3113 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3114 M_INTMOVE(REG_RESULT, d);
3115 emit_store_dst(jd, iptr, d);
3120 new_internalerror("Unknown ICMD %d", iptr->opc);
3124 } /* for instruction */
3126 } /* if (bptr -> flags >= BBREACHED) */
3127 } /* for basic block */
3129 dseg_createlinenumbertable(cd);
3131 /* generate stubs */
3133 emit_exception_stubs(jd);
3134 emit_patcher_stubs(jd);
3136 emit_replacement_stubs(jd);
3141 /* everything's ok */
3147 /* createcompilerstub **********************************************************
3149 Creates a stub routine which calls the compiler.
3151 *******************************************************************************/
3153 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3154 #define COMPILERSTUB_CODESIZE 3 * 4
3156 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3159 u1 *createcompilerstub(methodinfo *m)
3161 u1 *s; /* memory to hold the stub */
3165 s4 dumpsize; /* code generation pointer */
3167 s = CNEW(u1, COMPILERSTUB_SIZE);
3169 /* set data pointer and code pointer */
3172 s = s + COMPILERSTUB_DATASIZE;
3174 /* mark start of dump memory area */
3176 dumpsize = dump_size();
3178 cd = DNEW(codegendata);
3181 /* Store the codeinfo pointer in the same place as in the
3182 methodheader for compiled methods. */
3184 code = code_codeinfo_new(m);
3186 d[0] = (ptrint) asm_call_jit_compiler;
3188 d[2] = (ptrint) code;
3190 /* code for the stub */
3192 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3193 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3194 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3196 #if defined(ENABLE_STATISTICS)
3198 count_cstub_len += COMPILERSTUB_SIZE;
3201 /* release dump area */
3203 dump_release(dumpsize);
3209 /* createnativestub ************************************************************
3211 Creates a stub routine which calls a native method.
3213 *******************************************************************************/
3215 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3223 s4 i, j; /* count variables */
3226 s4 funcdisp; /* displacement of the function */
3228 /* get required compiler data */
3235 /* initialize variables */
3238 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3240 /* calculate stack frame size */
3242 cd->stackframesize =
3243 1 + /* return address */
3244 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3245 sizeof(localref_table) / SIZEOF_VOID_P +
3246 1 + /* methodinfo for call trace */
3247 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
3250 /* create method header */
3252 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3253 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3254 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3255 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3256 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3257 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3258 (void) dseg_addlinenumbertablesize(cd);
3259 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3261 /* generate stub code */
3263 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3264 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3266 /* call trace function */
3268 #if !defined(NDEBUG)
3269 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3270 emit_verbosecall_enter(jd);
3273 /* get function address (this must happen before the stackframeinfo) */
3275 funcdisp = dseg_add_functionptr(cd, f);
3277 #if !defined(WITH_STATIC_CLASSPATH)
3279 codegen_add_patch_ref(cd, PATCHER_resolve_native_function, m, funcdisp);
3282 /* save integer and float argument registers */
3284 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3285 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3286 M_LST(rd->argintregs[i], REG_SP, j * 8);
3291 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3292 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3293 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3298 /* prepare data structures for native function call */
3300 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3301 M_MOV(REG_PV, REG_A1);
3302 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3303 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3304 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3305 M_ALD(REG_PV, REG_PV, disp);
3306 M_JSR(REG_RA, REG_PV);
3307 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3308 M_LDA(REG_PV, REG_RA, -disp);
3310 /* restore integer and float argument registers */
3312 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3313 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3314 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3319 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3320 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3321 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3326 /* copy or spill arguments to new locations */
3328 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3329 t = md->paramtypes[i].type;
3331 if (IS_INT_LNG_TYPE(t)) {
3332 if (!md->params[i].inmemory) {
3333 s1 = rd->argintregs[md->params[i].regoff];
3335 if (!nmd->params[j].inmemory) {
3336 s2 = rd->argintregs[nmd->params[j].regoff];
3340 s2 = nmd->params[j].regoff;
3341 M_LST(s1, REG_SP, s2 * 8);
3345 s1 = md->params[i].regoff + cd->stackframesize;
3346 s2 = nmd->params[j].regoff;
3347 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3348 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3352 if (!md->params[i].inmemory) {
3353 s1 = rd->argfltregs[md->params[i].regoff];
3355 if (!nmd->params[j].inmemory) {
3356 s2 = rd->argfltregs[nmd->params[j].regoff];
3360 s2 = nmd->params[j].regoff;
3361 if (IS_2_WORD_TYPE(t))
3362 M_DST(s1, REG_SP, s2 * 8);
3364 M_FST(s1, REG_SP, s2 * 8);
3368 s1 = md->params[i].regoff + cd->stackframesize;
3369 s2 = nmd->params[j].regoff;
3370 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3371 if (IS_2_WORD_TYPE(t))
3372 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3374 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3379 /* put class into second argument register */
3381 if (m->flags & ACC_STATIC) {
3382 disp = dseg_add_address(cd, m->class);
3383 M_ALD(REG_A1, REG_PV, disp);
3386 /* put env into first argument register */
3388 disp = dseg_add_address(cd, _Jv_env);
3389 M_ALD(REG_A0, REG_PV, disp);
3391 /* do the native function call */
3393 M_ALD(REG_PV, REG_PV, funcdisp);
3394 M_JSR(REG_RA, REG_PV); /* call native method */
3395 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3396 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3398 /* save return value */
3400 if (md->returntype.type != TYPE_VOID) {
3401 if (IS_INT_LNG_TYPE(md->returntype.type))
3402 M_LST(REG_RESULT, REG_SP, 0 * 8);
3404 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3407 /* call finished trace */
3409 #if !defined(NDEBUG)
3410 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3411 emit_verbosecall_exit(jd);
3414 /* remove native stackframe info */
3416 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3417 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3418 M_ALD(REG_PV, REG_PV, disp);
3419 M_JSR(REG_RA, REG_PV);
3420 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3421 M_LDA(REG_PV, REG_RA, -disp);
3422 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3424 /* restore return value */
3426 if (md->returntype.type != TYPE_VOID) {
3427 if (IS_INT_LNG_TYPE(md->returntype.type))
3428 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3430 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3433 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3434 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3436 /* check for exception */
3438 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3439 M_RET(REG_ZERO, REG_RA); /* return to caller */
3441 /* handle exception */
3443 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3445 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3446 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3447 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3450 /* generate patcher stubs */
3452 emit_patcher_stubs(jd);
3456 return code->entrypoint;
3461 * These are local overrides for various environment variables in Emacs.
3462 * Please do not remove this and leave it at the end of the file, where
3463 * Emacs will automagically detect them.
3464 * ---------------------------------------------------------------------
3467 * indent-tabs-mode: t
3471 * vim:noexpandtab:sw=4:ts=4: