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
30 Changes: Joseph Wenninger
35 $Id: codegen.c 5948 2006-11-11 16:56:48Z twisti $
50 #include "vm/jit/alpha/arch.h"
51 #include "vm/jit/alpha/codegen.h"
53 #include "native/jni.h"
54 #include "native/native.h"
56 #if defined(ENABLE_THREADS)
57 # include "threads/native/lock.h"
60 #include "vm/builtin.h"
61 #include "vm/exceptions.h"
62 #include "vm/global.h"
63 #include "vm/loader.h"
64 #include "vm/options.h"
65 #include "vm/stringlocal.h"
67 #include "vm/jit/asmpart.h"
68 #include "vm/jit/codegen-common.h"
69 #include "vm/jit/dseg.h"
70 #include "vm/jit/emit-common.h"
71 #include "vm/jit/jit.h"
72 #include "vm/jit/parse.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
82 /* codegen *********************************************************************
84 Generates machine code.
86 *******************************************************************************/
88 bool codegen(jitdata *jd)
94 s4 len, s1, s2, s3, d, disp;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
106 rplpoint *replacementpoint;
110 /* get required compiler data */
117 /* prevent compiler warnings */
130 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
132 /* space to save used callee saved registers */
134 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
135 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
137 cd->stackframesize = rd->memuse + savedregs_num;
139 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
140 if (checksync && (m->flags & ACC_SYNCHRONIZED))
141 cd->stackframesize++;
144 /* create method header */
147 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
150 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
151 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
153 #if defined(ENABLE_THREADS)
154 /* IsSync contains the offset relative to the stack pointer for the
155 argument of monitor_exit used in the exception handler. Since the
156 offset could be zero and give a wrong meaning of the flag it is
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
164 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
166 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
167 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
168 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
170 dseg_addlinenumbertablesize(cd);
172 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
174 /* create exception table */
176 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
177 dseg_add_target(cd, ex->start);
178 dseg_add_target(cd, ex->end);
179 dseg_add_target(cd, ex->handler);
180 (void) dseg_add_unique_address(cd, ex->catchtype.any);
183 /* create stack frame (if necessary) */
185 if (cd->stackframesize)
186 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
188 /* save return address and used callee saved registers */
190 p = cd->stackframesize;
191 if (!jd->isleafmethod) {
192 p--; M_AST(REG_RA, REG_SP, p * 8);
194 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
195 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
197 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
198 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
201 /* take arguments out of register or stack frame */
205 for (p = 0, l = 0; p < md->paramcount; p++) {
206 t = md->paramtypes[p].type;
208 varindex = jd->local_map[l * 5 + t];
211 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
214 if (varindex == UNUSED)
219 s1 = md->params[p].regoff;
221 if (IS_INT_LNG_TYPE(t)) { /* integer args */
222 if (!md->params[p].inmemory) { /* register arguments */
223 s2 = rd->argintregs[s1];
224 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
225 M_INTMOVE(s2, var->vv.regoff);
227 } else { /* reg arg -> spilled */
228 M_LST(s2, REG_SP, var->vv.regoff * 8);
231 } else { /* stack arguments */
232 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
233 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) *8);
235 } else { /* stack arg -> spilled */
236 var->vv.regoff = cd->stackframesize + s1;
240 } else { /* floating args */
241 if (!md->params[p].inmemory) { /* register arguments */
242 s2 = rd->argfltregs[s1];
243 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
244 M_FLTMOVE(s2, var->vv.regoff);
246 } else { /* reg arg -> spilled */
247 M_DST(s2, REG_SP, var->vv.regoff * 8);
250 } else { /* stack arguments */
251 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
252 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
254 } else { /* stack-arg -> spilled */
255 var->vv.regoff = cd->stackframesize + s1;
261 /* call monitorenter function */
263 #if defined(ENABLE_THREADS)
264 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
265 /* stack offset for monitor argument */
270 if (opt_verbosecall) {
271 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
273 for (p = 0; p < INT_ARG_CNT; p++)
274 M_LST(rd->argintregs[p], REG_SP, p * 8);
276 for (p = 0; p < FLT_ARG_CNT; p++)
277 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
279 s1 += INT_ARG_CNT + FLT_ARG_CNT;
281 #endif /* !defined(NDEBUG) */
283 /* decide which monitor enter function to call */
285 if (m->flags & ACC_STATIC) {
286 disp = dseg_add_address(cd, &m->class->object.header);
287 M_ALD(REG_A0, REG_PV, disp);
291 codegen_add_nullpointerexception_ref(cd);
294 M_AST(REG_A0, REG_SP, s1 * 8);
295 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
296 M_ALD(REG_PV, REG_PV, disp);
297 M_JSR(REG_RA, REG_PV);
298 disp = (s4) (cd->mcodeptr - cd->mcodebase);
299 M_LDA(REG_PV, REG_RA, -disp);
302 if (opt_verbosecall) {
303 for (p = 0; p < INT_ARG_CNT; p++)
304 M_LLD(rd->argintregs[p], REG_SP, p * 8);
306 for (p = 0; p < FLT_ARG_CNT; p++)
307 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
309 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
311 #endif /* !defined(NDEBUG) */
315 /* call trace function */
318 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
319 emit_verbosecall_enter(jd);
324 /* end of header generation */
326 replacementpoint = jd->code->rplpoints;
328 /* walk through all basic blocks */
330 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
332 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
334 if (bptr->flags >= BBREACHED) {
336 /* branch resolving */
338 codegen_resolve_branchrefs(cd, bptr);
340 /* handle replacement points */
343 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
344 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
350 /* copy interface registers to their destination */
354 #if defined(ENABLE_LSRA)
358 src = bptr->invars[len];
359 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
360 /* d = reg_of_var(m, src, REG_ITMP1); */
361 if (!(src->flags & INMEMORY))
365 M_INTMOVE(REG_ITMP1, d);
366 emit_store(jd, NULL, src, d);
373 var = VAR(bptr->invars[len]);
374 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
375 d = codegen_reg_of_var(0, var, REG_ITMP1);
376 M_INTMOVE(REG_ITMP1, d);
377 emit_store(jd, NULL, var, d);
380 assert((var->flags & INOUT));
383 #if defined(ENABLE_LSRA)
387 /* walk through all instructions */
391 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
392 if (iptr->line != currentline) {
393 dseg_addlinenumber(cd, iptr->line);
394 currentline = iptr->line;
397 MCODECHECK(64); /* an instruction usually needs < 64 words */
400 case ICMD_INLINE_START:
401 case ICMD_INLINE_END:
404 case ICMD_NOP: /* ... ==> ... */
407 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
409 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
411 codegen_add_nullpointerexception_ref(cd);
414 /* constant operations ************************************************/
416 case ICMD_ICONST: /* ... ==> ..., constant */
418 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
419 ICONST(d, iptr->sx.val.i);
420 emit_store_dst(jd, iptr, d);
423 case ICMD_LCONST: /* ... ==> ..., constant */
425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
426 LCONST(d, iptr->sx.val.l);
427 emit_store_dst(jd, iptr, d);
430 case ICMD_FCONST: /* ... ==> ..., constant */
432 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
433 disp = dseg_add_float(cd, iptr->sx.val.f);
434 M_FLD(d, REG_PV, disp);
435 emit_store_dst(jd, iptr, d);
438 case ICMD_DCONST: /* ... ==> ..., constant */
440 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
441 disp = dseg_add_double(cd, iptr->sx.val.d);
442 M_DLD(d, REG_PV, disp);
443 emit_store_dst(jd, iptr, d);
446 case ICMD_ACONST: /* ... ==> ..., constant */
448 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
450 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
451 constant_classref *cr = iptr->sx.val.c.ref;
453 disp = dseg_add_unique_address(cd, cr);
455 /* XXX Only add the patcher, if this position needs to
456 be patched. If there was a previous position which
457 resolved the same class, the returned displacement
458 of dseg_addaddress is ok to use. */
460 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
463 if (opt_showdisassemble)
466 M_ALD(d, REG_PV, disp);
469 if (iptr->sx.val.anyptr == NULL)
470 M_INTMOVE(REG_ZERO, d);
472 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
473 M_ALD(d, REG_PV, disp);
476 emit_store_dst(jd, iptr, d);
480 /* load/store/move/copy operations ************************************/
482 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
483 case ICMD_ALOAD: /* s1 = local variable */
487 case ICMD_ISTORE: /* ..., value ==> ... */
488 case ICMD_ASTORE: /* dst = local variable */
495 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
499 /* pop operations *****************************************************/
501 /* attention: double and longs are only one entry in CACAO ICMDs */
503 case ICMD_POP: /* ..., value ==> ... */
504 case ICMD_POP2: /* ..., value, value ==> ... */
509 /* integer operations *************************************************/
511 case ICMD_INEG: /* ..., value ==> ..., - value */
513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
514 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
515 M_ISUB(REG_ZERO, s1, d);
516 emit_store_dst(jd, iptr, d);
519 case ICMD_LNEG: /* ..., value ==> ..., - value */
521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
523 M_LSUB(REG_ZERO, s1, d);
524 emit_store_dst(jd, iptr, d);
527 case ICMD_I2L: /* ..., value ==> ..., value */
529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
532 emit_store_dst(jd, iptr, d);
535 case ICMD_L2I: /* ..., value ==> ..., value */
537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
538 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
539 M_IADD(s1, REG_ZERO, d);
540 emit_store_dst(jd, iptr, d);
543 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
547 if (has_ext_instr_set) {
550 M_SLL_IMM(s1, 56, d);
551 M_SRA_IMM( d, 56, d);
553 emit_store_dst(jd, iptr, d);
556 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
559 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
561 emit_store_dst(jd, iptr, d);
564 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
568 if (has_ext_instr_set) {
571 M_SLL_IMM(s1, 48, d);
572 M_SRA_IMM( d, 48, d);
574 emit_store_dst(jd, iptr, d);
578 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
581 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
584 emit_store_dst(jd, iptr, d);
588 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
589 /* sx.val.i = constant */
591 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
593 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
594 M_IADD_IMM(s1, iptr->sx.val.i, d);
595 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
596 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
598 /* XXX maybe use M_LDA? */
599 ICONST(REG_ITMP2, iptr->sx.val.i);
600 M_IADD(s1, REG_ITMP2, d);
602 emit_store_dst(jd, iptr, d);
605 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
608 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
609 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 emit_store_dst(jd, iptr, d);
614 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
615 /* sx.val.l = constant */
617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
618 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
619 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
620 M_LADD_IMM(s1, iptr->sx.val.l, d);
622 LCONST(REG_ITMP2, iptr->sx.val.l);
623 M_LADD(s1, REG_ITMP2, d);
625 emit_store_dst(jd, iptr, d);
628 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
630 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
631 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
634 emit_store_dst(jd, iptr, d);
637 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
638 /* sx.val.i = constant */
640 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
642 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
643 M_ISUB_IMM(s1, iptr->sx.val.i, d);
645 ICONST(REG_ITMP2, iptr->sx.val.i);
646 M_ISUB(s1, REG_ITMP2, d);
648 emit_store_dst(jd, iptr, d);
651 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
657 emit_store_dst(jd, iptr, d);
660 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
661 /* sx.val.l = constant */
663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
664 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
665 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
666 M_LSUB_IMM(s1, iptr->sx.val.l, d);
668 LCONST(REG_ITMP2, iptr->sx.val.l);
669 M_LSUB(s1, REG_ITMP2, d);
671 emit_store_dst(jd, iptr, d);
674 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
678 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
680 emit_store_dst(jd, iptr, d);
683 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
684 /* sx.val.i = constant */
686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
688 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
689 M_IMUL_IMM(s1, iptr->sx.val.i, d);
691 ICONST(REG_ITMP2, iptr->sx.val.i);
692 M_IMUL(s1, REG_ITMP2, d);
694 emit_store_dst(jd, iptr, d);
697 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
703 emit_store_dst(jd, iptr, d);
706 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
707 /* sx.val.l = constant */
709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
711 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
712 M_LMUL_IMM(s1, iptr->sx.val.l, d);
714 LCONST(REG_ITMP2, iptr->sx.val.l);
715 M_LMUL(s1, REG_ITMP2, d);
717 emit_store_dst(jd, iptr, d);
720 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
721 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
724 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
725 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
727 codegen_add_arithmeticexception_ref(cd);
731 bte = iptr->sx.s23.s3.bte;
732 disp = dseg_add_functionptr(cd, bte->fp);
733 M_ALD(REG_PV, REG_PV, disp);
734 M_JSR(REG_RA, REG_PV);
735 disp = (s4) (cd->mcodeptr - cd->mcodebase);
736 M_LDA(REG_PV, REG_RA, -disp);
738 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
739 emit_store_dst(jd, iptr, d);
742 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
743 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
745 bte = iptr->sx.s23.s3.bte;
747 s1 = emit_load_s1(jd, iptr, REG_A0);
748 s2 = emit_load_s2(jd, iptr, REG_A1);
749 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
751 codegen_add_arithmeticexception_ref(cd);
753 M_INTMOVE(s1, REG_A0);
754 M_INTMOVE(s2, REG_A1);
755 disp = dseg_add_functionptr(cd, bte->fp);
756 M_ALD(REG_PV, REG_PV, disp);
757 M_JSR(REG_RA, REG_PV);
758 disp = (s4) (cd->mcodeptr - cd->mcodebase);
759 M_LDA(REG_PV, REG_RA, -disp);
761 M_INTMOVE(REG_RESULT, d);
762 emit_store_dst(jd, iptr, d);
765 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
766 case ICMD_LDIVPOW2: /* val.i = constant */
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
770 if (iptr->sx.val.i <= 15) {
771 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
772 M_CMOVGE(s1, s1, REG_ITMP2);
774 M_SRA_IMM(s1, 63, REG_ITMP2);
775 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
776 M_LADD(s1, REG_ITMP2, REG_ITMP2);
778 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
779 emit_store_dst(jd, iptr, d);
782 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
784 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
785 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
786 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
787 M_AND_IMM(s2, 0x1f, REG_ITMP3);
788 M_SLL(s1, REG_ITMP3, d);
789 M_IADD(d, REG_ZERO, d);
790 emit_store_dst(jd, iptr, d);
793 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
794 /* sx.val.i = constant */
796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
798 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
799 M_IADD(d, REG_ZERO, d);
800 emit_store_dst(jd, iptr, d);
803 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
807 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
808 M_AND_IMM(s2, 0x1f, REG_ITMP3);
809 M_SRA(s1, REG_ITMP3, d);
810 emit_store_dst(jd, iptr, d);
813 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
814 /* sx.val.i = constant */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
818 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
819 emit_store_dst(jd, iptr, d);
822 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
824 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
825 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827 M_AND_IMM(s2, 0x1f, REG_ITMP2);
829 M_SRL(d, REG_ITMP2, d);
830 M_IADD(d, REG_ZERO, d);
831 emit_store_dst(jd, iptr, d);
834 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
835 /* sx.val.i = constant */
837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
838 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
840 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
841 M_IADD(d, REG_ZERO, d);
842 emit_store_dst(jd, iptr, d);
845 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
849 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851 emit_store_dst(jd, iptr, d);
854 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
855 /* sx.val.i = constant */
857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
859 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869 emit_store_dst(jd, iptr, d);
872 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
873 /* sx.val.i = constant */
875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
876 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
877 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
878 emit_store_dst(jd, iptr, d);
881 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
884 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
887 emit_store_dst(jd, iptr, d);
890 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
891 /* sx.val.i = constant */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
895 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
896 emit_store_dst(jd, iptr, d);
899 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
902 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
903 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
904 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
906 emit_store_dst(jd, iptr, d);
909 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
910 /* sx.val.i = constant */
912 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
913 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
914 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
915 M_AND_IMM(s1, iptr->sx.val.i, d);
916 } else if (iptr->sx.val.i == 0xffff) {
918 } else if (iptr->sx.val.i == 0xffffff) {
919 M_ZAPNOT_IMM(s1, 0x07, d);
921 ICONST(REG_ITMP2, iptr->sx.val.i);
922 M_AND(s1, REG_ITMP2, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
928 /* sx.val.i = constant */
930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
933 M_MOV(s1, REG_ITMP1);
936 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
937 M_AND_IMM(s1, iptr->sx.val.i, d);
939 M_ISUB(REG_ZERO, s1, d);
940 M_AND_IMM(d, iptr->sx.val.i, d);
941 } else if (iptr->sx.val.i == 0xffff) {
944 M_ISUB(REG_ZERO, s1, d);
946 } else if (iptr->sx.val.i == 0xffffff) {
947 M_ZAPNOT_IMM(s1, 0x07, d);
949 M_ISUB(REG_ZERO, s1, d);
950 M_ZAPNOT_IMM(d, 0x07, d);
952 ICONST(REG_ITMP2, iptr->sx.val.i);
953 M_AND(s1, REG_ITMP2, d);
955 M_ISUB(REG_ZERO, s1, d);
956 M_AND(d, REG_ITMP2, d);
958 M_ISUB(REG_ZERO, d, d);
959 emit_store_dst(jd, iptr, d);
962 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
963 /* sx.val.l = constant */
965 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
966 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
967 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
968 M_AND_IMM(s1, iptr->sx.val.l, d);
969 } else if (iptr->sx.val.l == 0xffffL) {
971 } else if (iptr->sx.val.l == 0xffffffL) {
972 M_ZAPNOT_IMM(s1, 0x07, d);
973 } else if (iptr->sx.val.l == 0xffffffffL) {
975 } else if (iptr->sx.val.l == 0xffffffffffL) {
976 M_ZAPNOT_IMM(s1, 0x1f, d);
977 } else if (iptr->sx.val.l == 0xffffffffffffL) {
978 M_ZAPNOT_IMM(s1, 0x3f, d);
979 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
980 M_ZAPNOT_IMM(s1, 0x7f, d);
982 LCONST(REG_ITMP2, iptr->sx.val.l);
983 M_AND(s1, REG_ITMP2, d);
985 emit_store_dst(jd, iptr, d);
988 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
989 /* sx.val.l = constant */
991 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
992 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
994 M_MOV(s1, REG_ITMP1);
997 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
998 M_AND_IMM(s1, iptr->sx.val.l, d);
1000 M_LSUB(REG_ZERO, s1, d);
1001 M_AND_IMM(d, iptr->sx.val.l, d);
1002 } else if (iptr->sx.val.l == 0xffffL) {
1005 M_LSUB(REG_ZERO, s1, d);
1007 } else if (iptr->sx.val.l == 0xffffffL) {
1008 M_ZAPNOT_IMM(s1, 0x07, d);
1010 M_LSUB(REG_ZERO, s1, d);
1011 M_ZAPNOT_IMM(d, 0x07, d);
1012 } else if (iptr->sx.val.l == 0xffffffffL) {
1015 M_LSUB(REG_ZERO, s1, d);
1017 } else if (iptr->sx.val.l == 0xffffffffffL) {
1018 M_ZAPNOT_IMM(s1, 0x1f, d);
1020 M_LSUB(REG_ZERO, s1, d);
1021 M_ZAPNOT_IMM(d, 0x1f, d);
1022 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1023 M_ZAPNOT_IMM(s1, 0x3f, d);
1025 M_LSUB(REG_ZERO, s1, d);
1026 M_ZAPNOT_IMM(d, 0x3f, d);
1027 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1028 M_ZAPNOT_IMM(s1, 0x7f, d);
1030 M_LSUB(REG_ZERO, s1, d);
1031 M_ZAPNOT_IMM(d, 0x7f, d);
1033 LCONST(REG_ITMP2, iptr->sx.val.l);
1034 M_AND(s1, REG_ITMP2, d);
1036 M_LSUB(REG_ZERO, s1, d);
1037 M_AND(d, REG_ITMP2, d);
1039 M_LSUB(REG_ZERO, d, d);
1040 emit_store_dst(jd, iptr, d);
1043 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1046 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1047 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1048 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1050 emit_store_dst(jd, iptr, d);
1053 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1054 /* sx.val.i = constant */
1056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1057 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1058 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1059 M_OR_IMM(s1, iptr->sx.val.i, d);
1061 ICONST(REG_ITMP2, iptr->sx.val.i);
1062 M_OR(s1, REG_ITMP2, d);
1064 emit_store_dst(jd, iptr, d);
1067 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1068 /* sx.val.l = constant */
1070 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1071 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1072 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1073 M_OR_IMM(s1, iptr->sx.val.l, d);
1075 LCONST(REG_ITMP2, iptr->sx.val.l);
1076 M_OR(s1, REG_ITMP2, d);
1078 emit_store_dst(jd, iptr, d);
1081 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1084 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1085 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1086 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1092 /* sx.val.i = constant */
1094 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1095 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1096 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1097 M_XOR_IMM(s1, iptr->sx.val.i, d);
1099 ICONST(REG_ITMP2, iptr->sx.val.i);
1100 M_XOR(s1, REG_ITMP2, d);
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1106 /* sx.val.l = constant */
1108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1109 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1110 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1111 M_XOR_IMM(s1, iptr->sx.val.l, d);
1113 LCONST(REG_ITMP2, iptr->sx.val.l);
1114 M_XOR(s1, REG_ITMP2, d);
1116 emit_store_dst(jd, iptr, d);
1120 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1122 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1123 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1125 M_CMPLT(s1, s2, REG_ITMP3);
1126 M_CMPLT(s2, s1, REG_ITMP1);
1127 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1128 emit_store_dst(jd, iptr, d);
1132 /* floating operations ************************************************/
1134 case ICMD_FNEG: /* ..., value ==> ..., - value */
1136 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1137 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1139 emit_store_dst(jd, iptr, d);
1142 case ICMD_DNEG: /* ..., value ==> ..., - value */
1144 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1145 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1147 emit_store_dst(jd, iptr, d);
1150 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1152 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1153 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1154 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1158 if (d == s1 || d == s2) {
1159 M_FADDS(s1, s2, REG_FTMP3);
1161 M_FMOV(REG_FTMP3, d);
1167 emit_store_dst(jd, iptr, d);
1170 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1172 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1173 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1174 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1178 if (d == s1 || d == s2) {
1179 M_DADDS(s1, s2, REG_FTMP3);
1181 M_FMOV(REG_FTMP3, d);
1187 emit_store_dst(jd, iptr, d);
1190 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1192 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1193 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1194 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1198 if (d == s1 || d == s2) {
1199 M_FSUBS(s1, s2, REG_FTMP3);
1201 M_FMOV(REG_FTMP3, d);
1207 emit_store_dst(jd, iptr, d);
1210 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1212 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1213 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1214 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1218 if (d == s1 || d == s2) {
1219 M_DSUBS(s1, s2, REG_FTMP3);
1221 M_FMOV(REG_FTMP3, d);
1227 emit_store_dst(jd, iptr, d);
1230 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1232 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1233 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1234 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1238 if (d == s1 || d == s2) {
1239 M_FMULS(s1, s2, REG_FTMP3);
1241 M_FMOV(REG_FTMP3, d);
1247 emit_store_dst(jd, iptr, d);
1250 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1252 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1253 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1254 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1258 if (d == s1 || d == s2) {
1259 M_DMULS(s1, s2, REG_FTMP3);
1261 M_FMOV(REG_FTMP3, d);
1267 emit_store_dst(jd, iptr, d);
1270 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1272 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1273 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1274 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1278 if (d == s1 || d == s2) {
1279 M_FDIVS(s1, s2, REG_FTMP3);
1281 M_FMOV(REG_FTMP3, d);
1287 emit_store_dst(jd, iptr, d);
1290 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1292 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1293 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1294 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1298 if (d == s1 || d == s2) {
1299 M_DDIVS(s1, s2, REG_FTMP3);
1301 M_FMOV(REG_FTMP3, d);
1307 emit_store_dst(jd, iptr, d);
1310 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1312 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1313 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1314 disp = dseg_add_unique_double(cd, 0.0);
1315 M_LST(s1, REG_PV, disp);
1316 M_DLD(d, REG_PV, disp);
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1325 disp = dseg_add_unique_double(cd, 0.0);
1326 M_LST(s1, REG_PV, disp);
1327 M_DLD(d, REG_PV, disp);
1329 emit_store_dst(jd, iptr, d);
1332 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1334 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1335 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1336 disp = dseg_add_unique_double(cd, 0.0);
1337 M_CVTDL_C(s1, REG_FTMP2);
1338 M_CVTLI(REG_FTMP2, REG_FTMP3);
1339 M_DST(REG_FTMP3, REG_PV, disp);
1340 M_ILD(d, REG_PV, disp);
1341 emit_store_dst(jd, iptr, d);
1344 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1346 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1347 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1348 disp = dseg_add_unique_double(cd, 0.0);
1349 M_CVTDL_C(s1, REG_FTMP2);
1350 M_DST(REG_FTMP2, REG_PV, disp);
1351 M_LLD(d, REG_PV, disp);
1352 emit_store_dst(jd, iptr, d);
1355 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1357 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1358 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1361 emit_store_dst(jd, iptr, d);
1364 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1366 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1367 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1374 emit_store_dst(jd, iptr, d);
1377 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1379 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1380 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1381 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1383 M_LSUB_IMM(REG_ZERO, 1, d);
1384 M_FCMPEQ(s1, s2, REG_FTMP3);
1385 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1387 M_FCMPLT(s2, s1, REG_FTMP3);
1388 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1389 M_LADD_IMM(REG_ZERO, 1, d);
1391 M_LSUB_IMM(REG_ZERO, 1, d);
1392 M_FCMPEQS(s1, s2, REG_FTMP3);
1394 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1396 M_FCMPLTS(s2, s1, REG_FTMP3);
1398 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1399 M_LADD_IMM(REG_ZERO, 1, d);
1401 emit_store_dst(jd, iptr, d);
1404 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1406 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1407 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1408 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1410 M_LADD_IMM(REG_ZERO, 1, d);
1411 M_FCMPEQ(s1, s2, REG_FTMP3);
1412 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1414 M_FCMPLT(s1, s2, REG_FTMP3);
1415 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1416 M_LSUB_IMM(REG_ZERO, 1, d);
1418 M_LADD_IMM(REG_ZERO, 1, d);
1419 M_FCMPEQS(s1, s2, REG_FTMP3);
1421 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1423 M_FCMPLTS(s1, s2, REG_FTMP3);
1425 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1426 M_LSUB_IMM(REG_ZERO, 1, d);
1428 emit_store_dst(jd, iptr, d);
1432 /* memory operations **************************************************/
1434 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1437 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1438 gen_nullptr_check(s1);
1439 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1440 emit_store_dst(jd, iptr, d);
1443 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1446 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1448 if (INSTRUCTION_MUST_CHECK(iptr)) {
1449 gen_nullptr_check(s1);
1452 if (has_ext_instr_set) {
1453 M_LADD (s2, s1, REG_ITMP1);
1454 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1457 M_LADD(s2, s1, REG_ITMP1);
1458 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1459 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1460 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1461 M_SRA_IMM(d, 56, d);
1463 emit_store_dst(jd, iptr, d);
1466 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1468 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1469 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1470 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1471 if (INSTRUCTION_MUST_CHECK(iptr)) {
1472 gen_nullptr_check(s1);
1475 if (has_ext_instr_set) {
1476 M_LADD(s2, s1, REG_ITMP1);
1477 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1478 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1480 M_LADD (s2, s1, REG_ITMP1);
1481 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1482 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1483 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1484 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1486 emit_store_dst(jd, iptr, d);
1489 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1492 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1493 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1494 if (INSTRUCTION_MUST_CHECK(iptr)) {
1495 gen_nullptr_check(s1);
1498 if (has_ext_instr_set) {
1499 M_LADD(s2, s1, REG_ITMP1);
1500 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1501 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1504 M_LADD(s2, s1, REG_ITMP1);
1505 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1506 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1507 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1508 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1509 M_SRA_IMM(d, 48, d);
1511 emit_store_dst(jd, iptr, d);
1514 case ICMD_IALOAD: /* ..., 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 if (INSTRUCTION_MUST_CHECK(iptr)) {
1520 gen_nullptr_check(s1);
1523 M_S4ADDQ(s2, s1, REG_ITMP1);
1524 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1525 emit_store_dst(jd, iptr, d);
1528 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1531 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1533 if (INSTRUCTION_MUST_CHECK(iptr)) {
1534 gen_nullptr_check(s1);
1537 M_S8ADDQ(s2, s1, REG_ITMP1);
1538 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1539 emit_store_dst(jd, iptr, d);
1542 case ICMD_FALOAD: /* ..., 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_FTMP2);
1547 if (INSTRUCTION_MUST_CHECK(iptr)) {
1548 gen_nullptr_check(s1);
1551 M_S4ADDQ(s2, s1, REG_ITMP1);
1552 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1553 emit_store_dst(jd, iptr, d);
1556 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1559 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1560 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1561 if (INSTRUCTION_MUST_CHECK(iptr)) {
1562 gen_nullptr_check(s1);
1565 M_S8ADDQ(s2, s1, REG_ITMP1);
1566 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1567 emit_store_dst(jd, iptr, d);
1570 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1572 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1573 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1575 if (INSTRUCTION_MUST_CHECK(iptr)) {
1576 gen_nullptr_check(s1);
1579 M_SAADDQ(s2, s1, REG_ITMP1);
1580 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1581 emit_store_dst(jd, iptr, d);
1585 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1588 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1589 if (INSTRUCTION_MUST_CHECK(iptr)) {
1590 gen_nullptr_check(s1);
1593 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1594 if (has_ext_instr_set) {
1595 M_LADD(s2, s1, REG_ITMP1);
1596 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1598 M_LADD(s2, s1, REG_ITMP1);
1599 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1600 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1601 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1602 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1603 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1604 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1608 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1611 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1612 if (INSTRUCTION_MUST_CHECK(iptr)) {
1613 gen_nullptr_check(s1);
1616 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1617 if (has_ext_instr_set) {
1618 M_LADD(s2, s1, REG_ITMP1);
1619 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1620 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1622 M_LADD(s2, s1, REG_ITMP1);
1623 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1624 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1625 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1626 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1627 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1628 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1629 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1633 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1635 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1636 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1637 if (INSTRUCTION_MUST_CHECK(iptr)) {
1638 gen_nullptr_check(s1);
1641 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1642 if (has_ext_instr_set) {
1643 M_LADD(s2, s1, REG_ITMP1);
1644 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1645 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1647 M_LADD(s2, s1, REG_ITMP1);
1648 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1649 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1650 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1651 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1652 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1653 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1654 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1658 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1660 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1661 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1662 if (INSTRUCTION_MUST_CHECK(iptr)) {
1663 gen_nullptr_check(s1);
1666 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1667 M_S4ADDQ(s2, s1, REG_ITMP1);
1668 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1671 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1673 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1675 if (INSTRUCTION_MUST_CHECK(iptr)) {
1676 gen_nullptr_check(s1);
1679 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1680 M_S8ADDQ(s2, s1, REG_ITMP1);
1681 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1684 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1688 if (INSTRUCTION_MUST_CHECK(iptr)) {
1689 gen_nullptr_check(s1);
1692 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1693 M_S4ADDQ(s2, s1, REG_ITMP1);
1694 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1697 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1701 if (INSTRUCTION_MUST_CHECK(iptr)) {
1702 gen_nullptr_check(s1);
1705 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1706 M_S8ADDQ(s2, s1, REG_ITMP1);
1707 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1710 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1712 s1 = emit_load_s1(jd, iptr, REG_A0);
1713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1714 if (INSTRUCTION_MUST_CHECK(iptr)) {
1715 gen_nullptr_check(s1);
1718 s3 = emit_load_s3(jd, iptr, REG_A1);
1720 M_INTMOVE(s1, REG_A0);
1721 M_INTMOVE(s3, REG_A1);
1723 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1724 M_ALD(REG_PV, REG_PV, disp);
1725 M_JSR(REG_RA, REG_PV);
1726 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1727 M_LDA(REG_PV, REG_RA, -disp);
1729 M_BEQZ(REG_RESULT, 0);
1730 codegen_add_arraystoreexception_ref(cd);
1732 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1733 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1734 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1735 M_SAADDQ(s2, s1, REG_ITMP1);
1736 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1740 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1744 if (INSTRUCTION_MUST_CHECK(iptr)) {
1745 gen_nullptr_check(s1);
1748 M_S4ADDQ(s2, s1, REG_ITMP1);
1749 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1752 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1754 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1755 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1756 if (INSTRUCTION_MUST_CHECK(iptr)) {
1757 gen_nullptr_check(s1);
1760 M_S8ADDQ(s2, s1, REG_ITMP1);
1761 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1764 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1768 if (INSTRUCTION_MUST_CHECK(iptr)) {
1769 gen_nullptr_check(s1);
1772 M_SAADDQ(s2, s1, REG_ITMP1);
1773 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1776 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1779 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1780 if (INSTRUCTION_MUST_CHECK(iptr)) {
1781 gen_nullptr_check(s1);
1784 if (has_ext_instr_set) {
1785 M_LADD(s2, s1, REG_ITMP1);
1786 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1789 M_LADD(s2, s1, REG_ITMP1);
1790 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1791 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1792 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1793 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1794 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1795 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1799 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1802 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1803 if (INSTRUCTION_MUST_CHECK(iptr)) {
1804 gen_nullptr_check(s1);
1807 if (has_ext_instr_set) {
1808 M_LADD(s2, s1, REG_ITMP1);
1809 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1810 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1813 M_LADD(s2, s1, REG_ITMP1);
1814 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1815 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1816 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1817 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1818 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1819 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1820 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1824 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1827 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1828 if (INSTRUCTION_MUST_CHECK(iptr)) {
1829 gen_nullptr_check(s1);
1832 if (has_ext_instr_set) {
1833 M_LADD(s2, s1, REG_ITMP1);
1834 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1835 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1838 M_LADD(s2, s1, REG_ITMP1);
1839 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1840 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1841 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1842 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1843 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1844 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1845 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1850 case ICMD_GETSTATIC: /* ... ==> ..., value */
1852 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1853 uf = iptr->sx.s23.s3.uf;
1855 fieldtype = uf->fieldref->parseddesc.fd->type;
1857 disp = dseg_add_unique_address(cd, uf);
1859 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1861 if (opt_showdisassemble)
1865 fi = iptr->sx.s23.s3.fmiref->p.field;
1867 fieldtype = fi->type;
1868 disp = dseg_add_address(cd, &(fi->value));
1870 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1871 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1874 if (opt_showdisassemble)
1879 M_ALD(REG_ITMP1, REG_PV, disp);
1880 switch (fieldtype) {
1882 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1883 M_ILD(d, REG_ITMP1, 0);
1886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1887 M_LLD(d, REG_ITMP1, 0);
1890 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1891 M_ALD(d, REG_ITMP1, 0);
1894 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1895 M_FLD(d, REG_ITMP1, 0);
1898 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1899 M_DLD(d, REG_ITMP1, 0);
1902 emit_store_dst(jd, iptr, d);
1905 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1907 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1908 uf = iptr->sx.s23.s3.uf;
1910 fieldtype = uf->fieldref->parseddesc.fd->type;
1912 disp = dseg_add_unique_address(cd, uf);
1914 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1916 if (opt_showdisassemble)
1920 fi = iptr->sx.s23.s3.fmiref->p.field;
1922 fieldtype = fi->type;
1923 disp = dseg_add_address(cd, &(fi->value));
1925 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1926 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1929 if (opt_showdisassemble)
1934 M_ALD(REG_ITMP1, REG_PV, disp);
1935 switch (fieldtype) {
1937 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1938 M_IST(s1, REG_ITMP1, 0);
1941 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1942 M_LST(s1, REG_ITMP1, 0);
1945 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1946 M_AST(s1, REG_ITMP1, 0);
1949 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1950 M_FST(s1, REG_ITMP1, 0);
1953 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1954 M_DST(s1, REG_ITMP1, 0);
1959 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1960 /* val = value (in current instruction) */
1961 /* following NOP) */
1963 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1964 uf = iptr->sx.s23.s3.uf;
1966 fieldtype = uf->fieldref->parseddesc.fd->type;
1968 disp = dseg_add_unique_address(cd, uf);
1970 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1972 if (opt_showdisassemble)
1976 fi = iptr->sx.s23.s3.fmiref->p.field;
1978 fieldtype = fi->type;
1979 disp = dseg_add_address(cd, &(fi->value));
1981 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1982 codegen_addpatchref(cd, PATCHER_initialize_class, fi->class,
1985 if (opt_showdisassemble)
1990 M_ALD(REG_ITMP1, REG_PV, disp);
1991 switch (fieldtype) {
1993 M_IST(REG_ZERO, REG_ITMP1, 0);
1996 M_LST(REG_ZERO, REG_ITMP1, 0);
1999 M_AST(REG_ZERO, REG_ITMP1, 0);
2002 M_FST(REG_ZERO, REG_ITMP1, 0);
2005 M_DST(REG_ZERO, REG_ITMP1, 0);
2011 case ICMD_GETFIELD: /* ... ==> ..., value */
2013 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2014 gen_nullptr_check(s1);
2016 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2017 uf = iptr->sx.s23.s3.uf;
2019 fieldtype = uf->fieldref->parseddesc.fd->type;
2021 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2023 if (opt_showdisassemble)
2029 fi = iptr->sx.s23.s3.fmiref->p.field;
2031 fieldtype = fi->type;
2035 switch (fieldtype) {
2037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2041 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2045 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2049 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2053 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2057 emit_store_dst(jd, iptr, d);
2060 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2063 gen_nullptr_check(s1);
2065 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2066 uf = iptr->sx.s23.s3.uf;
2067 fieldtype = uf->fieldref->parseddesc.fd->type;
2072 fi = iptr->sx.s23.s3.fmiref->p.field;
2073 fieldtype = fi->type;
2077 if (IS_INT_LNG_TYPE(fieldtype))
2078 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2080 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2082 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2083 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2085 if (opt_showdisassemble)
2089 switch (fieldtype) {
2091 M_IST(s2, s1, disp);
2094 M_LST(s2, s1, disp);
2097 M_AST(s2, s1, disp);
2100 M_FST(s2, s1, disp);
2103 M_DST(s2, s1, disp);
2108 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2109 /* val = value (in current instruction) */
2110 /* following NOP) */
2112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2113 gen_nullptr_check(s1);
2115 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2116 uf = iptr->sx.s23.s3.uf;
2118 fieldtype = uf->fieldref->parseddesc.fd->type;
2120 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2122 if (opt_showdisassemble)
2128 fi = iptr->sx.s23.s3.fmiref->p.field;
2130 fieldtype = fi->type;
2134 switch (fieldtype) {
2136 M_IST(REG_ZERO, s1, disp);
2139 M_LST(REG_ZERO, s1, disp);
2142 M_AST(REG_ZERO, s1, disp);
2145 M_FST(REG_ZERO, s1, disp);
2148 M_DST(REG_ZERO, s1, disp);
2154 /* branch operations **************************************************/
2156 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2159 M_INTMOVE(s1, REG_ITMP1_XPTR);
2161 #ifdef ENABLE_VERIFIER
2162 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2163 unresolved_class *uc = iptr->sx.s23.s2.uc;
2165 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2167 if (opt_showdisassemble)
2170 #endif /* ENABLE_VERIFIER */
2172 disp = dseg_add_functionptr(cd, asm_handle_exception);
2173 M_ALD(REG_ITMP2, REG_PV, disp);
2174 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2175 M_NOP; /* nop ensures that XPC is less than the end */
2176 /* of basic block */
2180 case ICMD_GOTO: /* ... ==> ... */
2181 case ICMD_RET: /* ... ==> ... */
2184 codegen_addreference(cd, iptr->dst.block);
2188 case ICMD_JSR: /* ... ==> ... */
2191 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
2195 case ICMD_IFNULL: /* ..., value ==> ... */
2197 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2199 codegen_addreference(cd, iptr->dst.block);
2202 case ICMD_IFNONNULL: /* ..., value ==> ... */
2204 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2206 codegen_addreference(cd, iptr->dst.block);
2209 case ICMD_IFEQ: /* ..., value ==> ... */
2211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2212 if (iptr->sx.val.i == 0) {
2216 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2217 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2220 ICONST(REG_ITMP2, iptr->sx.val.i);
2221 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2223 M_BNEZ(REG_ITMP1, 0);
2225 codegen_addreference(cd, iptr->dst.block);
2228 case ICMD_IFLT: /* ..., value ==> ... */
2230 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2231 if (iptr->sx.val.i == 0) {
2235 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2236 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2239 ICONST(REG_ITMP2, iptr->sx.val.i);
2240 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2242 M_BNEZ(REG_ITMP1, 0);
2244 codegen_addreference(cd, iptr->dst.block);
2247 case ICMD_IFLE: /* ..., value ==> ... */
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2250 if (iptr->sx.val.i == 0) {
2254 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2255 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2258 ICONST(REG_ITMP2, iptr->sx.val.i);
2259 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2261 M_BNEZ(REG_ITMP1, 0);
2263 codegen_addreference(cd, iptr->dst.block);
2266 case ICMD_IFNE: /* ..., value ==> ... */
2268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269 if (iptr->sx.val.i == 0) {
2273 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2274 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2277 ICONST(REG_ITMP2, iptr->sx.val.i);
2278 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2280 M_BEQZ(REG_ITMP1, 0);
2282 codegen_addreference(cd, iptr->dst.block);
2285 case ICMD_IFGT: /* ..., value ==> ... */
2287 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2288 if (iptr->sx.val.i == 0) {
2292 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2293 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2296 ICONST(REG_ITMP2, iptr->sx.val.i);
2297 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2299 M_BEQZ(REG_ITMP1, 0);
2301 codegen_addreference(cd, iptr->dst.block);
2304 case ICMD_IFGE: /* ..., value ==> ... */
2306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2307 if (iptr->sx.val.i == 0) {
2311 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2312 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2315 ICONST(REG_ITMP2, iptr->sx.val.i);
2316 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2318 M_BEQZ(REG_ITMP1, 0);
2320 codegen_addreference(cd, iptr->dst.block);
2323 case ICMD_IF_LEQ: /* ..., value ==> ... */
2325 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2326 if (iptr->sx.val.l == 0) {
2330 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2331 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2334 LCONST(REG_ITMP2, iptr->sx.val.l);
2335 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2337 M_BNEZ(REG_ITMP1, 0);
2339 codegen_addreference(cd, iptr->dst.block);
2342 case ICMD_IF_LLT: /* ..., value ==> ... */
2344 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2345 if (iptr->sx.val.l == 0) {
2349 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2350 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2353 LCONST(REG_ITMP2, iptr->sx.val.l);
2354 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2356 M_BNEZ(REG_ITMP1, 0);
2358 codegen_addreference(cd, iptr->dst.block);
2361 case ICMD_IF_LLE: /* ..., value ==> ... */
2363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2364 if (iptr->sx.val.l == 0) {
2368 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2369 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2372 LCONST(REG_ITMP2, iptr->sx.val.l);
2373 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2375 M_BNEZ(REG_ITMP1, 0);
2377 codegen_addreference(cd, iptr->dst.block);
2380 case ICMD_IF_LNE: /* ..., value ==> ... */
2382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2383 if (iptr->sx.val.l == 0) {
2387 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2388 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2391 LCONST(REG_ITMP2, iptr->sx.val.l);
2392 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2394 M_BEQZ(REG_ITMP1, 0);
2396 codegen_addreference(cd, iptr->dst.block);
2399 case ICMD_IF_LGT: /* ..., value ==> ... */
2401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2402 if (iptr->sx.val.l == 0) {
2406 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2407 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2410 LCONST(REG_ITMP2, iptr->sx.val.l);
2411 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2413 M_BEQZ(REG_ITMP1, 0);
2415 codegen_addreference(cd, iptr->dst.block);
2418 case ICMD_IF_LGE: /* ..., value ==> ... */
2420 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2421 if (iptr->sx.val.l == 0) {
2425 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2426 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2429 LCONST(REG_ITMP2, iptr->sx.val.l);
2430 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2432 M_BEQZ(REG_ITMP1, 0);
2434 codegen_addreference(cd, iptr->dst.block);
2437 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2438 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2439 case ICMD_IF_ACMPEQ:
2441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2442 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2443 M_CMPEQ(s1, s2, REG_ITMP1);
2444 M_BNEZ(REG_ITMP1, 0);
2445 codegen_addreference(cd, iptr->dst.block);
2448 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2449 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2450 case ICMD_IF_ACMPNE:
2452 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2453 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2454 M_CMPEQ(s1, s2, REG_ITMP1);
2455 M_BEQZ(REG_ITMP1, 0);
2456 codegen_addreference(cd, iptr->dst.block);
2459 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2460 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2463 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2464 M_CMPLT(s1, s2, REG_ITMP1);
2465 M_BNEZ(REG_ITMP1, 0);
2466 codegen_addreference(cd, iptr->dst.block);
2469 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2470 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2473 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2474 M_CMPLE(s1, s2, REG_ITMP1);
2475 M_BEQZ(REG_ITMP1, 0);
2476 codegen_addreference(cd, iptr->dst.block);
2479 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2480 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2483 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2484 M_CMPLE(s1, s2, REG_ITMP1);
2485 M_BNEZ(REG_ITMP1, 0);
2486 codegen_addreference(cd, iptr->dst.block);
2489 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2490 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2492 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2493 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2494 M_CMPLT(s1, s2, REG_ITMP1);
2495 M_BEQZ(REG_ITMP1, 0);
2496 codegen_addreference(cd, iptr->dst.block);
2500 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2503 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2504 M_INTMOVE(s1, REG_RESULT);
2505 goto nowperformreturn;
2507 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2509 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2510 M_INTMOVE(s1, REG_RESULT);
2512 #ifdef ENABLE_VERIFIER
2513 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2514 unresolved_class *uc = iptr->sx.s23.s2.uc;
2516 codegen_addpatchref(cd, PATCHER_resolve_class, uc, 0);
2518 if (opt_showdisassemble)
2521 #endif /* ENABLE_VERIFIER */
2522 goto nowperformreturn;
2524 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2527 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2528 M_FLTMOVE(s1, REG_FRESULT);
2529 goto nowperformreturn;
2531 case ICMD_RETURN: /* ... ==> ... */
2537 p = cd->stackframesize;
2539 /* call trace function */
2541 #if !defined(NDEBUG)
2542 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2543 emit_verbosecall_exit(jd);
2546 #if defined(ENABLE_THREADS)
2547 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2548 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2550 switch (iptr->opc) {
2554 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2558 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2562 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2563 M_ALD(REG_PV, REG_PV, disp);
2564 M_JSR(REG_RA, REG_PV);
2565 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2566 M_LDA(REG_PV, REG_RA, disp);
2568 switch (iptr->opc) {
2572 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2576 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2582 /* restore return address */
2584 if (!jd->isleafmethod) {
2585 p--; M_LLD(REG_RA, REG_SP, p * 8);
2588 /* restore saved registers */
2590 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2591 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2593 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2594 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2597 /* deallocate stack */
2599 if (cd->stackframesize)
2600 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2602 M_RET(REG_ZERO, REG_RA);
2608 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2611 branch_target_t *table;
2613 table = iptr->dst.table;
2615 l = iptr->sx.s23.s2.tablelow;
2616 i = iptr->sx.s23.s3.tablehigh;
2618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2620 M_INTMOVE(s1, REG_ITMP1);
2621 } else if (l <= 32768) {
2622 M_LDA(REG_ITMP1, s1, -l);
2624 ICONST(REG_ITMP2, l);
2625 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2628 /* number of targets */
2634 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2636 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2637 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2639 M_BEQZ(REG_ITMP2, 0);
2640 codegen_addreference(cd, table[0].block);
2642 /* build jump table top down and use address of lowest entry */
2647 dseg_add_target(cd, table->block);
2652 /* length of dataseg after last dseg_add_target is used by load */
2654 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2655 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2656 M_JMP(REG_ZERO, REG_ITMP2);
2661 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2664 lookup_target_t *lookup;
2666 lookup = iptr->dst.lookup;
2668 i = iptr->sx.s23.s2.lookupcount;
2670 MCODECHECK((i<<2)+8);
2671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2674 val = lookup->value;
2675 if ((val >= 0) && (val <= 255)) {
2676 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2678 if ((val >= -32768) && (val <= 32767)) {
2679 M_LDA(REG_ITMP2, REG_ZERO, val);
2681 disp = dseg_add_s4(cd, val);
2682 M_ILD(REG_ITMP2, REG_PV, disp);
2684 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2686 M_BNEZ(REG_ITMP2, 0);
2687 codegen_addreference(cd, lookup->target.block);
2693 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2700 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2702 bte = iptr->sx.s23.s3.bte;
2706 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2708 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2709 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2710 case ICMD_INVOKEINTERFACE:
2712 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2714 um = iptr->sx.s23.s3.um;
2715 md = um->methodref->parseddesc.md;
2718 lm = iptr->sx.s23.s3.fmiref->p.method;
2720 md = lm->parseddesc;
2724 s3 = md->paramcount;
2726 MCODECHECK((s3 << 1) + 64);
2728 /* copy arguments to registers or stack location */
2730 for (s3 = s3 - 1; s3 >= 0; s3--) {
2731 var = VAR(iptr->sx.s23.s2.args[s3]);
2733 /* Already Preallocated (ARGVAR) ? */
2734 if (var->flags & PREALLOC)
2737 if (IS_INT_LNG_TYPE(var->type)) {
2738 if (!md->params[s3].inmemory) {
2739 s1 = rd->argintregs[md->params[s3].regoff];
2740 d = emit_load(jd, iptr, var, s1);
2744 d = emit_load(jd, iptr, var, REG_ITMP1);
2745 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2749 if (!md->params[s3].inmemory) {
2750 s1 = rd->argfltregs[md->params[s3].regoff];
2751 d = emit_load(jd, iptr, var, s1);
2755 d = emit_load(jd, iptr, var, REG_FTMP1);
2756 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2761 switch (iptr->opc) {
2763 disp = dseg_add_functionptr(cd, bte->fp);
2765 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2768 case ICMD_INVOKESPECIAL:
2770 codegen_add_nullpointerexception_ref(cd);
2773 case ICMD_INVOKESTATIC:
2775 disp = dseg_add_unique_address(cd, um);
2777 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2780 if (opt_showdisassemble)
2784 disp = dseg_add_address(cd, lm->stubroutine);
2786 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2789 case ICMD_INVOKEVIRTUAL:
2790 gen_nullptr_check(REG_A0);
2793 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2795 if (opt_showdisassemble)
2801 s1 = OFFSET(vftbl_t, table[0]) +
2802 sizeof(methodptr) * lm->vftblindex;
2804 M_ALD(REG_METHODPTR, REG_A0,
2805 OFFSET(java_objectheader, vftbl));
2806 M_ALD(REG_PV, REG_METHODPTR, s1);
2809 case ICMD_INVOKEINTERFACE:
2810 gen_nullptr_check(REG_A0);
2813 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2815 if (opt_showdisassemble)
2822 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2823 sizeof(methodptr*) * lm->class->index;
2825 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2828 M_ALD(REG_METHODPTR, REG_A0,
2829 OFFSET(java_objectheader, vftbl));
2830 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2831 M_ALD(REG_PV, REG_METHODPTR, s2);
2835 /* generate the actual call */
2837 M_JSR(REG_RA, REG_PV);
2838 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2839 M_LDA(REG_PV, REG_RA, -disp);
2841 /* actually only used for ICMD_BUILTIN */
2843 if (INSTRUCTION_MUST_CHECK(iptr)) {
2844 M_BEQZ(REG_RESULT, 0);
2845 codegen_add_fillinstacktrace_ref(cd);
2848 /* store the return value */
2850 d = md->returntype.type;
2852 if (d != TYPE_VOID) {
2853 if (IS_INT_LNG_TYPE(d)) {
2854 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2855 M_INTMOVE(REG_RESULT, s1);
2858 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2859 M_FLTMOVE(REG_FRESULT, s1);
2861 emit_store_dst(jd, iptr, s1);
2866 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2868 /* val.a: (classinfo*) superclass */
2870 /* superclass is an interface:
2872 * OK if ((sub == NULL) ||
2873 * (sub->vftbl->interfacetablelength > super->index) &&
2874 * (sub->vftbl->interfacetable[-super->index] != NULL));
2876 * superclass is a class:
2878 * OK if ((sub == NULL) || (0
2879 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2880 * super->vftbl->diffval));
2883 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2884 /* object type cast-check */
2887 vftbl_t *supervftbl;
2890 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2896 super = iptr->sx.s23.s3.c.cls;
2897 superindex = super->index;
2898 supervftbl = super->vftbl;
2901 #if defined(ENABLE_THREADS)
2902 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2906 /* calculate interface checkcast code size */
2910 s2 += opt_showdisassemble ? 1 : 0;
2912 /* calculate class checkcast code size */
2914 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
2916 s3 += opt_showdisassemble ? 1 : 0;
2918 /* if class is not resolved, check which code to call */
2920 if (super == NULL) {
2921 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
2923 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2925 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
2926 iptr->sx.s23.s3.c.ref,
2929 if (opt_showdisassemble)
2932 M_ILD(REG_ITMP2, REG_PV, disp);
2933 disp = dseg_add_s4(cd, ACC_INTERFACE);
2934 M_ILD(REG_ITMP3, REG_PV, disp);
2935 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2936 M_BEQZ(REG_ITMP2, s2 + 1);
2939 /* interface checkcast code */
2941 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2942 if (super == NULL) {
2943 codegen_addpatchref(cd,
2944 PATCHER_checkcast_instanceof_interface,
2945 iptr->sx.s23.s3.c.ref,
2948 if (opt_showdisassemble)
2954 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2955 M_ILD(REG_ITMP3, REG_ITMP2,
2956 OFFSET(vftbl_t, interfacetablelength));
2957 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2958 M_BLEZ(REG_ITMP3, 0);
2959 codegen_add_classcastexception_ref(cd, s1);
2960 M_ALD(REG_ITMP3, REG_ITMP2,
2961 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2962 superindex * sizeof(methodptr*)));
2963 M_BEQZ(REG_ITMP3, 0);
2964 codegen_add_classcastexception_ref(cd, s1);
2970 /* class checkcast code */
2972 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2973 if (super == NULL) {
2974 disp = dseg_add_unique_address(cd, NULL);
2976 codegen_addpatchref(cd,
2977 PATCHER_resolve_classref_to_vftbl,
2978 iptr->sx.s23.s3.c.ref,
2981 if (opt_showdisassemble)
2985 disp = dseg_add_address(cd, supervftbl);
2990 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2991 M_ALD(REG_ITMP3, REG_PV, disp);
2992 #if defined(ENABLE_THREADS)
2993 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2995 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2996 /* if (s1 != REG_ITMP1) { */
2997 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2998 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2999 /* #if defined(ENABLE_THREADS) */
3000 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3002 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3005 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3006 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3007 M_ALD(REG_ITMP3, REG_PV, disp);
3008 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3009 #if defined(ENABLE_THREADS)
3010 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3013 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3014 M_BEQZ(REG_ITMP3, 0);
3015 codegen_add_classcastexception_ref(cd, s1);
3018 d = codegen_reg_of_dst(jd, iptr, s1);
3021 /* array type cast-check */
3023 s1 = emit_load_s1(jd, iptr, REG_A0);
3024 M_INTMOVE(s1, REG_A0);
3026 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3028 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3029 codegen_addpatchref(cd,
3030 PATCHER_resolve_classref_to_classinfo,
3031 iptr->sx.s23.s3.c.ref,
3034 if (opt_showdisassemble)
3038 M_ALD(REG_A1, REG_PV, disp);
3039 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3040 M_ALD(REG_PV, REG_PV, disp);
3041 M_JSR(REG_RA, REG_PV);
3042 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3043 M_LDA(REG_PV, REG_RA, -disp);
3045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3046 M_BEQZ(REG_RESULT, 0);
3047 codegen_add_classcastexception_ref(cd, s1);
3049 d = codegen_reg_of_dst(jd, iptr, s1);
3053 emit_store_dst(jd, iptr, d);
3056 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3058 /* val.a: (classinfo*) superclass */
3060 /* superclass is an interface:
3062 * return (sub != NULL) &&
3063 * (sub->vftbl->interfacetablelength > super->index) &&
3064 * (sub->vftbl->interfacetable[-super->index] != NULL);
3066 * superclass is a class:
3068 * return ((sub != NULL) && (0
3069 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3070 * super->vftbl->diffvall));
3075 vftbl_t *supervftbl;
3078 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3084 super = iptr->sx.s23.s3.c.cls;
3085 superindex = super->index;
3086 supervftbl = super->vftbl;
3089 #if defined(ENABLE_THREADS)
3090 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3095 M_MOV(s1, REG_ITMP1);
3099 /* calculate interface instanceof code size */
3103 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3105 /* calculate class instanceof code size */
3109 s3 += (opt_showdisassemble ? 1 : 0);
3111 /* if class is not resolved, check which code to call */
3113 if (super == NULL) {
3115 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3117 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3119 codegen_addpatchref(cd, PATCHER_resolve_classref_to_flags,
3120 iptr->sx.s23.s3.c.ref, disp);
3122 if (opt_showdisassemble)
3125 M_ILD(REG_ITMP3, REG_PV, disp);
3127 disp = dseg_add_s4(cd, ACC_INTERFACE);
3128 M_ILD(REG_ITMP2, REG_PV, disp);
3129 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3130 M_BEQZ(REG_ITMP3, s2 + 1);
3133 /* interface instanceof code */
3135 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3136 if (super == NULL) {
3137 /* If d == REG_ITMP2, then it's destroyed in check
3142 codegen_addpatchref(cd,
3143 PATCHER_checkcast_instanceof_interface,
3144 iptr->sx.s23.s3.c.ref, 0);
3146 if (opt_showdisassemble)
3154 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3155 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3156 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3157 M_BLEZ(REG_ITMP3, 2);
3158 M_ALD(REG_ITMP1, REG_ITMP1,
3159 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3160 superindex * sizeof(methodptr*)));
3161 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3167 /* class instanceof code */
3169 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3170 if (super == NULL) {
3171 disp = dseg_add_unique_address(cd, NULL);
3173 codegen_addpatchref(cd, PATCHER_resolve_classref_to_vftbl,
3174 iptr->sx.s23.s3.c.ref,
3177 if (opt_showdisassemble)
3181 disp = dseg_add_address(cd, supervftbl);
3187 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3188 M_ALD(REG_ITMP2, REG_PV, disp);
3189 #if defined(ENABLE_THREADS)
3190 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3192 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3193 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3194 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3195 #if defined(ENABLE_THREADS)
3196 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3198 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3199 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3201 emit_store_dst(jd, iptr, d);
3205 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3207 /* check for negative sizes and copy sizes to stack if necessary */
3209 MCODECHECK((iptr->s1.argcount << 1) + 64);
3211 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3213 var = VAR(iptr->sx.s23.s2.args[s1]);
3215 /* copy SAVEDVAR sizes to stack */
3217 /* Already Preallocated? */
3219 if (!(var->flags & PREALLOC)) {
3220 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3221 M_LST(s2, REG_SP, s1 * 8);
3225 /* a0 = dimension count */
3227 ICONST(REG_A0, iptr->s1.argcount);
3229 /* is patcher function set? */
3231 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3232 disp = dseg_add_unique_address(cd, 0);
3234 codegen_addpatchref(cd, PATCHER_resolve_classref_to_classinfo,
3235 iptr->sx.s23.s3.c.ref,
3238 if (opt_showdisassemble)
3242 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3244 /* a1 = arraydescriptor */
3246 M_ALD(REG_A1, REG_PV, disp);
3248 /* a2 = pointer to dimensions = stack pointer */
3250 M_INTMOVE(REG_SP, REG_A2);
3252 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3253 M_ALD(REG_PV, REG_PV, disp);
3254 M_JSR(REG_RA, REG_PV);
3255 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3256 M_LDA(REG_PV, REG_RA, -disp);
3258 /* check for exception before result assignment */
3260 M_BEQZ(REG_RESULT, 0);
3261 codegen_add_fillinstacktrace_ref(cd);
3263 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3264 M_INTMOVE(REG_RESULT, d);
3265 emit_store_dst(jd, iptr, d);
3270 new_internalerror("Unknown ICMD %d", iptr->opc);
3274 } /* for instruction */
3276 } /* if (bptr -> flags >= BBREACHED) */
3277 } /* for basic block */
3279 dseg_createlinenumbertable(cd);
3281 /* generate stubs */
3283 emit_exception_stubs(jd);
3284 emit_patcher_stubs(jd);
3286 emit_replacement_stubs(jd);
3291 /* everything's ok */
3297 /* createcompilerstub **********************************************************
3299 Creates a stub routine which calls the compiler.
3301 *******************************************************************************/
3303 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3304 #define COMPILERSTUB_CODESIZE 3 * 4
3306 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3309 u1 *createcompilerstub(methodinfo *m)
3311 u1 *s; /* memory to hold the stub */
3315 s4 dumpsize; /* code generation pointer */
3317 s = CNEW(u1, COMPILERSTUB_SIZE);
3319 /* set data pointer and code pointer */
3322 s = s + COMPILERSTUB_DATASIZE;
3324 /* mark start of dump memory area */
3326 dumpsize = dump_size();
3328 cd = DNEW(codegendata);
3331 /* Store the codeinfo pointer in the same place as in the
3332 methodheader for compiled methods. */
3334 code = code_codeinfo_new(m);
3336 d[0] = (ptrint) asm_call_jit_compiler;
3338 d[2] = (ptrint) code;
3340 /* code for the stub */
3342 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3343 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3344 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3346 #if defined(ENABLE_STATISTICS)
3348 count_cstub_len += COMPILERSTUB_SIZE;
3351 /* release dump area */
3353 dump_release(dumpsize);
3359 /* createnativestub ************************************************************
3361 Creates a stub routine which calls a native method.
3363 *******************************************************************************/
3365 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3373 s4 i, j; /* count variables */
3376 s4 funcdisp; /* displacement of the function */
3378 /* get required compiler data */
3385 /* initialize variables */
3388 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3390 /* calculate stack frame size */
3392 cd->stackframesize =
3393 1 + /* return address */
3394 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3395 sizeof(localref_table) / SIZEOF_VOID_P +
3396 1 + /* methodinfo for call trace */
3397 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
3400 /* create method header */
3402 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3403 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3404 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3405 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3406 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3407 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3408 (void) dseg_addlinenumbertablesize(cd);
3409 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3411 /* generate stub code */
3413 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3414 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3416 /* call trace function */
3418 #if !defined(NDEBUG)
3419 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3420 emit_verbosecall_enter(jd);
3423 /* get function address (this must happen before the stackframeinfo) */
3425 funcdisp = dseg_add_functionptr(cd, f);
3427 #if !defined(WITH_STATIC_CLASSPATH)
3429 codegen_addpatchref(cd, PATCHER_resolve_native_function, m, funcdisp);
3431 if (opt_showdisassemble)
3436 /* save integer and float argument registers */
3438 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3439 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3440 M_LST(rd->argintregs[i], REG_SP, j * 8);
3445 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3446 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3447 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3452 /* prepare data structures for native function call */
3454 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3455 M_MOV(REG_PV, REG_A1);
3456 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3457 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3458 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3459 M_ALD(REG_PV, REG_PV, disp);
3460 M_JSR(REG_RA, REG_PV);
3461 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3462 M_LDA(REG_PV, REG_RA, -disp);
3464 /* restore integer and float argument registers */
3466 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3467 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3468 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3473 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3474 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3475 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3480 /* copy or spill arguments to new locations */
3482 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3483 t = md->paramtypes[i].type;
3485 if (IS_INT_LNG_TYPE(t)) {
3486 if (!md->params[i].inmemory) {
3487 s1 = rd->argintregs[md->params[i].regoff];
3489 if (!nmd->params[j].inmemory) {
3490 s2 = rd->argintregs[nmd->params[j].regoff];
3494 s2 = nmd->params[j].regoff;
3495 M_LST(s1, REG_SP, s2 * 8);
3499 s1 = md->params[i].regoff + cd->stackframesize;
3500 s2 = nmd->params[j].regoff;
3501 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3502 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3506 if (!md->params[i].inmemory) {
3507 s1 = rd->argfltregs[md->params[i].regoff];
3509 if (!nmd->params[j].inmemory) {
3510 s2 = rd->argfltregs[nmd->params[j].regoff];
3514 s2 = nmd->params[j].regoff;
3515 if (IS_2_WORD_TYPE(t))
3516 M_DST(s1, REG_SP, s2 * 8);
3518 M_FST(s1, REG_SP, s2 * 8);
3522 s1 = md->params[i].regoff + cd->stackframesize;
3523 s2 = nmd->params[j].regoff;
3524 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3525 if (IS_2_WORD_TYPE(t))
3526 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3528 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3533 /* put class into second argument register */
3535 if (m->flags & ACC_STATIC) {
3536 disp = dseg_add_address(cd, m->class);
3537 M_ALD(REG_A1, REG_PV, disp);
3540 /* put env into first argument register */
3542 disp = dseg_add_address(cd, _Jv_env);
3543 M_ALD(REG_A0, REG_PV, disp);
3545 /* do the native function call */
3547 M_ALD(REG_PV, REG_PV, funcdisp);
3548 M_JSR(REG_RA, REG_PV); /* call native method */
3549 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3550 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3552 /* save return value */
3554 if (md->returntype.type != TYPE_VOID) {
3555 if (IS_INT_LNG_TYPE(md->returntype.type))
3556 M_LST(REG_RESULT, REG_SP, 0 * 8);
3558 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3561 /* call finished trace */
3563 #if !defined(NDEBUG)
3564 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3565 emit_verbosecall_exit(jd);
3568 /* remove native stackframe info */
3570 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3571 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3572 M_ALD(REG_PV, REG_PV, disp);
3573 M_JSR(REG_RA, REG_PV);
3574 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3575 M_LDA(REG_PV, REG_RA, -disp);
3576 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3578 /* restore return value */
3580 if (md->returntype.type != TYPE_VOID) {
3581 if (IS_INT_LNG_TYPE(md->returntype.type))
3582 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3584 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3587 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3588 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3590 /* check for exception */
3592 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3593 M_RET(REG_ZERO, REG_RA); /* return to caller */
3595 /* handle exception */
3597 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3599 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3600 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3601 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3604 /* generate patcher stubs */
3606 emit_patcher_stubs(jd);
3610 return code->entrypoint;
3615 * These are local overrides for various environment variables in Emacs.
3616 * Please do not remove this and leave it at the end of the file, where
3617 * Emacs will automagically detect them.
3618 * ---------------------------------------------------------------------
3621 * indent-tabs-mode: t
3625 * vim:noexpandtab:sw=4:ts=4: