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 6165 2006-12-10 22:07:02Z 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;
108 /* get required compiler data */
115 /* prevent compiler warnings */
128 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
130 /* space to save used callee saved registers */
132 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
133 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
135 cd->stackframesize = rd->memuse + savedregs_num;
137 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
138 if (checksync && (m->flags & ACC_SYNCHRONIZED))
139 cd->stackframesize++;
142 /* create method header */
145 cd->stackframesize = (cd->stackframesize + 1) & ~1; /* align stack to 16-bytes */
148 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
149 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
151 #if defined(ENABLE_THREADS)
152 /* IsSync contains the offset relative to the stack pointer for the
153 argument of monitor_exit used in the exception handler. Since the
154 offset could be zero and give a wrong meaning of the flag it is
158 if (checksync && (m->flags & ACC_SYNCHRONIZED))
159 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
162 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
164 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
165 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
166 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
168 dseg_addlinenumbertablesize(cd);
170 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
172 /* create exception table */
174 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
175 dseg_add_target(cd, ex->start);
176 dseg_add_target(cd, ex->end);
177 dseg_add_target(cd, ex->handler);
178 (void) dseg_add_unique_address(cd, ex->catchtype.any);
181 /* create stack frame (if necessary) */
183 if (cd->stackframesize)
184 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
186 /* save return address and used callee saved registers */
188 p = cd->stackframesize;
189 if (!jd->isleafmethod) {
190 p--; M_AST(REG_RA, REG_SP, p * 8);
192 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
193 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
195 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
196 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
199 /* take arguments out of register or stack frame */
203 for (p = 0, l = 0; p < md->paramcount; p++) {
204 t = md->paramtypes[p].type;
206 varindex = jd->local_map[l * 5 + t];
209 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
212 if (varindex == UNUSED)
217 s1 = md->params[p].regoff;
219 if (IS_INT_LNG_TYPE(t)) { /* integer args */
220 if (!md->params[p].inmemory) { /* register arguments */
221 s2 = rd->argintregs[s1];
222 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
223 M_INTMOVE(s2, var->vv.regoff);
225 } else { /* reg arg -> spilled */
226 M_LST(s2, REG_SP, var->vv.regoff * 8);
229 } else { /* stack arguments */
230 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
231 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) *8);
233 } else { /* stack arg -> spilled */
234 var->vv.regoff = cd->stackframesize + s1;
238 } else { /* floating args */
239 if (!md->params[p].inmemory) { /* register arguments */
240 s2 = rd->argfltregs[s1];
241 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
242 M_FLTMOVE(s2, var->vv.regoff);
244 } else { /* reg arg -> spilled */
245 M_DST(s2, REG_SP, var->vv.regoff * 8);
248 } else { /* stack arguments */
249 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
250 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
252 } else { /* stack-arg -> spilled */
253 var->vv.regoff = cd->stackframesize + s1;
259 /* call monitorenter function */
261 #if defined(ENABLE_THREADS)
262 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
263 /* stack offset for monitor argument */
268 if (opt_verbosecall) {
269 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
271 for (p = 0; p < INT_ARG_CNT; p++)
272 M_LST(rd->argintregs[p], REG_SP, p * 8);
274 for (p = 0; p < FLT_ARG_CNT; p++)
275 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
277 s1 += INT_ARG_CNT + FLT_ARG_CNT;
279 #endif /* !defined(NDEBUG) */
281 /* decide which monitor enter function to call */
283 if (m->flags & ACC_STATIC) {
284 disp = dseg_add_address(cd, &m->class->object.header);
285 M_ALD(REG_A0, REG_PV, disp);
289 codegen_add_nullpointerexception_ref(cd);
292 M_AST(REG_A0, REG_SP, s1 * 8);
293 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
294 M_ALD(REG_PV, REG_PV, disp);
295 M_JSR(REG_RA, REG_PV);
296 disp = (s4) (cd->mcodeptr - cd->mcodebase);
297 M_LDA(REG_PV, REG_RA, -disp);
300 if (opt_verbosecall) {
301 for (p = 0; p < INT_ARG_CNT; p++)
302 M_LLD(rd->argintregs[p], REG_SP, p * 8);
304 for (p = 0; p < FLT_ARG_CNT; p++)
305 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
307 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
309 #endif /* !defined(NDEBUG) */
313 /* call trace function */
316 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
317 emit_verbosecall_enter(jd);
322 /* end of header generation */
324 /* create replacement points */
326 REPLACEMENT_POINTS_INIT(cd, jd);
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 */
342 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
344 /* copy interface registers to their destination */
348 #if defined(ENABLE_LSRA)
352 src = bptr->invars[len];
353 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
354 /* d = reg_of_var(m, src, REG_ITMP1); */
355 if (!(src->flags & INMEMORY))
359 M_INTMOVE(REG_ITMP1, d);
360 emit_store(jd, NULL, src, d);
367 var = VAR(bptr->invars[len]);
368 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
369 d = codegen_reg_of_var(0, var, REG_ITMP1);
370 M_INTMOVE(REG_ITMP1, d);
371 emit_store(jd, NULL, var, d);
374 assert((var->flags & INOUT));
377 #if defined(ENABLE_LSRA)
381 /* walk through all instructions */
385 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
386 if (iptr->line != currentline) {
387 dseg_addlinenumber(cd, iptr->line);
388 currentline = iptr->line;
391 MCODECHECK(64); /* an instruction usually needs < 64 words */
394 case ICMD_NOP: /* ... ==> ... */
395 case ICMD_POP: /* ..., value ==> ... */
396 case ICMD_POP2: /* ..., value, value ==> ... */
399 case ICMD_INLINE_START:
401 REPLACEMENT_POINT_INLINE_START(cd, iptr);
404 case ICMD_INLINE_BODY:
406 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
407 dseg_addlinenumber_inline_start(cd, iptr);
408 dseg_addlinenumber(cd, iptr->line);
411 case ICMD_INLINE_END:
413 dseg_addlinenumber_inline_end(cd, iptr);
414 dseg_addlinenumber(cd, iptr->line);
417 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
420 emit_nullpointer_check(cd, iptr, s1);
423 /* constant operations ************************************************/
425 case ICMD_ICONST: /* ... ==> ..., constant */
427 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
428 ICONST(d, iptr->sx.val.i);
429 emit_store_dst(jd, iptr, d);
432 case ICMD_LCONST: /* ... ==> ..., constant */
434 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
435 LCONST(d, iptr->sx.val.l);
436 emit_store_dst(jd, iptr, d);
439 case ICMD_FCONST: /* ... ==> ..., constant */
441 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
442 disp = dseg_add_float(cd, iptr->sx.val.f);
443 M_FLD(d, REG_PV, disp);
444 emit_store_dst(jd, iptr, d);
447 case ICMD_DCONST: /* ... ==> ..., constant */
449 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
450 disp = dseg_add_double(cd, iptr->sx.val.d);
451 M_DLD(d, REG_PV, disp);
452 emit_store_dst(jd, iptr, d);
455 case ICMD_ACONST: /* ... ==> ..., constant */
457 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
459 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
460 constant_classref *cr = iptr->sx.val.c.ref;
462 disp = dseg_add_unique_address(cd, cr);
464 /* XXX Only add the patcher, if this position needs to
465 be patched. If there was a previous position which
466 resolved the same class, the returned displacement
467 of dseg_add_address is ok to use. */
469 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
472 M_ALD(d, REG_PV, disp);
475 if (iptr->sx.val.anyptr == NULL)
476 M_INTMOVE(REG_ZERO, d);
478 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
479 M_ALD(d, REG_PV, disp);
482 emit_store_dst(jd, iptr, d);
486 /* load/store/move/copy operations ************************************/
488 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
489 case ICMD_ALOAD: /* s1 = local variable */
493 case ICMD_ISTORE: /* ..., value ==> ... */
500 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
505 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
506 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
510 /* integer operations *************************************************/
512 case ICMD_INEG: /* ..., value ==> ..., - value */
514 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
516 M_ISUB(REG_ZERO, s1, d);
517 emit_store_dst(jd, iptr, d);
520 case ICMD_LNEG: /* ..., value ==> ..., - value */
522 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
524 M_LSUB(REG_ZERO, s1, d);
525 emit_store_dst(jd, iptr, d);
528 case ICMD_I2L: /* ..., value ==> ..., value */
530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
533 emit_store_dst(jd, iptr, d);
536 case ICMD_L2I: /* ..., value ==> ..., value */
538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
540 M_IADD(s1, REG_ZERO, d);
541 emit_store_dst(jd, iptr, d);
544 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
548 if (has_ext_instr_set) {
551 M_SLL_IMM(s1, 56, d);
552 M_SRA_IMM( d, 56, d);
554 emit_store_dst(jd, iptr, d);
557 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
562 emit_store_dst(jd, iptr, d);
565 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
567 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
568 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
569 if (has_ext_instr_set) {
572 M_SLL_IMM(s1, 48, d);
573 M_SRA_IMM( d, 48, d);
575 emit_store_dst(jd, iptr, d);
579 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
582 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
585 emit_store_dst(jd, iptr, d);
589 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
590 /* sx.val.i = constant */
592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
594 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
595 M_IADD_IMM(s1, iptr->sx.val.i, d);
596 } else if ((iptr->sx.val.i > -256) && (iptr->sx.val.i < 0)) {
597 M_ISUB_IMM(s1, (-iptr->sx.val.i), d);
599 /* XXX maybe use M_LDA? */
600 ICONST(REG_ITMP2, iptr->sx.val.i);
601 M_IADD(s1, REG_ITMP2, d);
603 emit_store_dst(jd, iptr, d);
606 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
612 emit_store_dst(jd, iptr, d);
615 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
616 /* sx.val.l = constant */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
620 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
621 M_LADD_IMM(s1, iptr->sx.val.l, d);
623 LCONST(REG_ITMP2, iptr->sx.val.l);
624 M_LADD(s1, REG_ITMP2, d);
626 emit_store_dst(jd, iptr, d);
629 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
635 emit_store_dst(jd, iptr, d);
638 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
639 /* sx.val.i = constant */
641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
643 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
644 M_ISUB_IMM(s1, iptr->sx.val.i, d);
646 ICONST(REG_ITMP2, iptr->sx.val.i);
647 M_ISUB(s1, REG_ITMP2, d);
649 emit_store_dst(jd, iptr, d);
652 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658 emit_store_dst(jd, iptr, d);
661 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
662 /* sx.val.l = constant */
664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
666 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
667 M_LSUB_IMM(s1, iptr->sx.val.l, d);
669 LCONST(REG_ITMP2, iptr->sx.val.l);
670 M_LSUB(s1, REG_ITMP2, d);
672 emit_store_dst(jd, iptr, d);
675 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
679 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
681 emit_store_dst(jd, iptr, d);
684 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
685 /* sx.val.i = constant */
687 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
689 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
690 M_IMUL_IMM(s1, iptr->sx.val.i, d);
692 ICONST(REG_ITMP2, iptr->sx.val.i);
693 M_IMUL(s1, REG_ITMP2, d);
695 emit_store_dst(jd, iptr, d);
698 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
701 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
704 emit_store_dst(jd, iptr, d);
707 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
708 /* sx.val.l = constant */
710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
711 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
712 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
713 M_LMUL_IMM(s1, iptr->sx.val.l, d);
715 LCONST(REG_ITMP2, iptr->sx.val.l);
716 M_LMUL(s1, REG_ITMP2, d);
718 emit_store_dst(jd, iptr, d);
721 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
722 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
726 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
728 codegen_add_arithmeticexception_ref(cd);
732 bte = iptr->sx.s23.s3.bte;
733 disp = dseg_add_functionptr(cd, bte->fp);
734 M_ALD(REG_PV, REG_PV, disp);
735 M_JSR(REG_RA, REG_PV);
736 disp = (s4) (cd->mcodeptr - cd->mcodebase);
737 M_LDA(REG_PV, REG_RA, -disp);
739 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
740 emit_store_dst(jd, iptr, d);
743 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
744 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
746 bte = iptr->sx.s23.s3.bte;
748 s1 = emit_load_s1(jd, iptr, REG_A0);
749 s2 = emit_load_s2(jd, iptr, REG_A1);
750 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
752 codegen_add_arithmeticexception_ref(cd);
754 M_INTMOVE(s1, REG_A0);
755 M_INTMOVE(s2, REG_A1);
756 disp = dseg_add_functionptr(cd, bte->fp);
757 M_ALD(REG_PV, REG_PV, disp);
758 M_JSR(REG_RA, REG_PV);
759 disp = (s4) (cd->mcodeptr - cd->mcodebase);
760 M_LDA(REG_PV, REG_RA, -disp);
762 M_INTMOVE(REG_RESULT, d);
763 emit_store_dst(jd, iptr, d);
766 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
767 case ICMD_LDIVPOW2: /* val.i = constant */
769 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
771 if (iptr->sx.val.i <= 15) {
772 M_LDA(REG_ITMP2, s1, (1 << iptr->sx.val.i) -1);
773 M_CMOVGE(s1, s1, REG_ITMP2);
775 M_SRA_IMM(s1, 63, REG_ITMP2);
776 M_SRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
777 M_LADD(s1, REG_ITMP2, REG_ITMP2);
779 M_SRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
780 emit_store_dst(jd, iptr, d);
783 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
786 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
787 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
788 M_AND_IMM(s2, 0x1f, REG_ITMP3);
789 M_SLL(s1, REG_ITMP3, d);
790 M_IADD(d, REG_ZERO, d);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
795 /* sx.val.i = constant */
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
799 M_SLL_IMM(s1, iptr->sx.val.i & 0x1f, d);
800 M_IADD(d, REG_ZERO, d);
801 emit_store_dst(jd, iptr, d);
804 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
808 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
809 M_AND_IMM(s2, 0x1f, REG_ITMP3);
810 M_SRA(s1, REG_ITMP3, d);
811 emit_store_dst(jd, iptr, d);
814 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
815 /* sx.val.i = constant */
817 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
818 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
819 M_SRA_IMM(s1, iptr->sx.val.i & 0x1f, d);
820 emit_store_dst(jd, iptr, d);
823 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
827 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828 M_AND_IMM(s2, 0x1f, REG_ITMP2);
830 M_SRL(d, REG_ITMP2, d);
831 M_IADD(d, REG_ZERO, d);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
836 /* sx.val.i = constant */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
841 M_SRL_IMM(d, iptr->sx.val.i & 0x1f, d);
842 M_IADD(d, REG_ZERO, d);
843 emit_store_dst(jd, iptr, d);
846 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
848 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
849 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
852 emit_store_dst(jd, iptr, d);
855 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
856 /* sx.val.i = constant */
858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
859 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860 M_SLL_IMM(s1, iptr->sx.val.i & 0x3f, d);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
866 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
867 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
870 emit_store_dst(jd, iptr, d);
873 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
874 /* sx.val.i = constant */
876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
877 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
878 M_SRA_IMM(s1, iptr->sx.val.i & 0x3f, d);
879 emit_store_dst(jd, iptr, d);
882 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
885 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
886 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
888 emit_store_dst(jd, iptr, d);
891 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
892 /* sx.val.i = constant */
894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
896 M_SRL_IMM(s1, iptr->sx.val.i & 0x3f, d);
897 emit_store_dst(jd, iptr, d);
900 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
907 emit_store_dst(jd, iptr, d);
910 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
911 /* sx.val.i = constant */
913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
914 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
915 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
916 M_AND_IMM(s1, iptr->sx.val.i, d);
917 } else if (iptr->sx.val.i == 0xffff) {
919 } else if (iptr->sx.val.i == 0xffffff) {
920 M_ZAPNOT_IMM(s1, 0x07, d);
922 ICONST(REG_ITMP2, iptr->sx.val.i);
923 M_AND(s1, REG_ITMP2, d);
925 emit_store_dst(jd, iptr, d);
928 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
929 /* sx.val.i = constant */
931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
932 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
934 M_MOV(s1, REG_ITMP1);
937 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
938 M_AND_IMM(s1, iptr->sx.val.i, d);
940 M_ISUB(REG_ZERO, s1, d);
941 M_AND_IMM(d, iptr->sx.val.i, d);
942 } else if (iptr->sx.val.i == 0xffff) {
945 M_ISUB(REG_ZERO, s1, d);
947 } else if (iptr->sx.val.i == 0xffffff) {
948 M_ZAPNOT_IMM(s1, 0x07, d);
950 M_ISUB(REG_ZERO, s1, d);
951 M_ZAPNOT_IMM(d, 0x07, d);
953 ICONST(REG_ITMP2, iptr->sx.val.i);
954 M_AND(s1, REG_ITMP2, d);
956 M_ISUB(REG_ZERO, s1, d);
957 M_AND(d, REG_ITMP2, d);
959 M_ISUB(REG_ZERO, d, d);
960 emit_store_dst(jd, iptr, d);
963 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
964 /* sx.val.l = constant */
966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
968 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
969 M_AND_IMM(s1, iptr->sx.val.l, d);
970 } else if (iptr->sx.val.l == 0xffffL) {
972 } else if (iptr->sx.val.l == 0xffffffL) {
973 M_ZAPNOT_IMM(s1, 0x07, d);
974 } else if (iptr->sx.val.l == 0xffffffffL) {
976 } else if (iptr->sx.val.l == 0xffffffffffL) {
977 M_ZAPNOT_IMM(s1, 0x1f, d);
978 } else if (iptr->sx.val.l == 0xffffffffffffL) {
979 M_ZAPNOT_IMM(s1, 0x3f, d);
980 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
981 M_ZAPNOT_IMM(s1, 0x7f, d);
983 LCONST(REG_ITMP2, iptr->sx.val.l);
984 M_AND(s1, REG_ITMP2, d);
986 emit_store_dst(jd, iptr, d);
989 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
990 /* sx.val.l = constant */
992 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
993 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
995 M_MOV(s1, REG_ITMP1);
998 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
999 M_AND_IMM(s1, iptr->sx.val.l, d);
1001 M_LSUB(REG_ZERO, s1, d);
1002 M_AND_IMM(d, iptr->sx.val.l, d);
1003 } else if (iptr->sx.val.l == 0xffffL) {
1006 M_LSUB(REG_ZERO, s1, d);
1008 } else if (iptr->sx.val.l == 0xffffffL) {
1009 M_ZAPNOT_IMM(s1, 0x07, d);
1011 M_LSUB(REG_ZERO, s1, d);
1012 M_ZAPNOT_IMM(d, 0x07, d);
1013 } else if (iptr->sx.val.l == 0xffffffffL) {
1016 M_LSUB(REG_ZERO, s1, d);
1018 } else if (iptr->sx.val.l == 0xffffffffffL) {
1019 M_ZAPNOT_IMM(s1, 0x1f, d);
1021 M_LSUB(REG_ZERO, s1, d);
1022 M_ZAPNOT_IMM(d, 0x1f, d);
1023 } else if (iptr->sx.val.l == 0xffffffffffffL) {
1024 M_ZAPNOT_IMM(s1, 0x3f, d);
1026 M_LSUB(REG_ZERO, s1, d);
1027 M_ZAPNOT_IMM(d, 0x3f, d);
1028 } else if (iptr->sx.val.l == 0xffffffffffffffL) {
1029 M_ZAPNOT_IMM(s1, 0x7f, d);
1031 M_LSUB(REG_ZERO, s1, d);
1032 M_ZAPNOT_IMM(d, 0x7f, d);
1034 LCONST(REG_ITMP2, iptr->sx.val.l);
1035 M_AND(s1, REG_ITMP2, d);
1037 M_LSUB(REG_ZERO, s1, d);
1038 M_AND(d, REG_ITMP2, d);
1040 M_LSUB(REG_ZERO, d, d);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1047 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1048 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1051 emit_store_dst(jd, iptr, d);
1054 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1055 /* sx.val.i = constant */
1057 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1058 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1059 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1060 M_OR_IMM(s1, iptr->sx.val.i, d);
1062 ICONST(REG_ITMP2, iptr->sx.val.i);
1063 M_OR(s1, REG_ITMP2, d);
1065 emit_store_dst(jd, iptr, d);
1068 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1069 /* sx.val.l = constant */
1071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1072 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1073 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1074 M_OR_IMM(s1, iptr->sx.val.l, d);
1076 LCONST(REG_ITMP2, iptr->sx.val.l);
1077 M_OR(s1, REG_ITMP2, d);
1079 emit_store_dst(jd, iptr, d);
1082 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1086 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1087 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1089 emit_store_dst(jd, iptr, d);
1092 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1093 /* sx.val.i = constant */
1095 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1096 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1097 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 255)) {
1098 M_XOR_IMM(s1, iptr->sx.val.i, d);
1100 ICONST(REG_ITMP2, iptr->sx.val.i);
1101 M_XOR(s1, REG_ITMP2, d);
1103 emit_store_dst(jd, iptr, d);
1106 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1107 /* sx.val.l = constant */
1109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1110 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1111 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 255)) {
1112 M_XOR_IMM(s1, iptr->sx.val.l, d);
1114 LCONST(REG_ITMP2, iptr->sx.val.l);
1115 M_XOR(s1, REG_ITMP2, d);
1117 emit_store_dst(jd, iptr, d);
1121 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1124 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1125 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1126 M_CMPLT(s1, s2, REG_ITMP3);
1127 M_CMPLT(s2, s1, REG_ITMP1);
1128 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1129 emit_store_dst(jd, iptr, d);
1133 /* floating operations ************************************************/
1135 case ICMD_FNEG: /* ..., value ==> ..., - value */
1137 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1138 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1140 emit_store_dst(jd, iptr, d);
1143 case ICMD_DNEG: /* ..., value ==> ..., - value */
1145 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1146 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1153 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1154 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1155 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1159 if (d == s1 || d == s2) {
1160 M_FADDS(s1, s2, REG_FTMP3);
1162 M_FMOV(REG_FTMP3, d);
1168 emit_store_dst(jd, iptr, d);
1171 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1173 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1174 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1175 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1179 if (d == s1 || d == s2) {
1180 M_DADDS(s1, s2, REG_FTMP3);
1182 M_FMOV(REG_FTMP3, d);
1188 emit_store_dst(jd, iptr, d);
1191 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1193 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1194 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1195 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1199 if (d == s1 || d == s2) {
1200 M_FSUBS(s1, s2, REG_FTMP3);
1202 M_FMOV(REG_FTMP3, d);
1208 emit_store_dst(jd, iptr, d);
1211 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1213 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1214 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1215 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1219 if (d == s1 || d == s2) {
1220 M_DSUBS(s1, s2, REG_FTMP3);
1222 M_FMOV(REG_FTMP3, d);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1233 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1234 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1235 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1239 if (d == s1 || d == s2) {
1240 M_FMULS(s1, s2, REG_FTMP3);
1242 M_FMOV(REG_FTMP3, d);
1248 emit_store_dst(jd, iptr, d);
1251 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1253 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1254 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1255 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1259 if (d == s1 || d == s2) {
1260 M_DMULS(s1, s2, REG_FTMP3);
1262 M_FMOV(REG_FTMP3, d);
1268 emit_store_dst(jd, iptr, d);
1271 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1273 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1274 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1275 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1279 if (d == s1 || d == s2) {
1280 M_FDIVS(s1, s2, REG_FTMP3);
1282 M_FMOV(REG_FTMP3, d);
1288 emit_store_dst(jd, iptr, d);
1291 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1293 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1294 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1295 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1299 if (d == s1 || d == s2) {
1300 M_DDIVS(s1, s2, REG_FTMP3);
1302 M_FMOV(REG_FTMP3, d);
1308 emit_store_dst(jd, iptr, d);
1311 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1314 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1315 disp = dseg_add_unique_double(cd, 0.0);
1316 M_LST(s1, REG_PV, disp);
1317 M_DLD(d, REG_PV, disp);
1319 emit_store_dst(jd, iptr, d);
1322 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1324 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1325 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1326 disp = dseg_add_unique_double(cd, 0.0);
1327 M_LST(s1, REG_PV, disp);
1328 M_DLD(d, REG_PV, disp);
1330 emit_store_dst(jd, iptr, d);
1333 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1335 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1336 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1337 disp = dseg_add_unique_double(cd, 0.0);
1338 M_CVTDL_C(s1, REG_FTMP2);
1339 M_CVTLI(REG_FTMP2, REG_FTMP3);
1340 M_DST(REG_FTMP3, REG_PV, disp);
1341 M_ILD(d, REG_PV, disp);
1342 emit_store_dst(jd, iptr, d);
1345 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1347 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1348 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1349 disp = dseg_add_unique_double(cd, 0.0);
1350 M_CVTDL_C(s1, REG_FTMP2);
1351 M_DST(REG_FTMP2, REG_PV, disp);
1352 M_LLD(d, REG_PV, disp);
1353 emit_store_dst(jd, iptr, d);
1356 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1358 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1359 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1362 emit_store_dst(jd, iptr, d);
1365 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1367 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1368 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1375 emit_store_dst(jd, iptr, d);
1378 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1380 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1381 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1382 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1384 M_LSUB_IMM(REG_ZERO, 1, d);
1385 M_FCMPEQ(s1, s2, REG_FTMP3);
1386 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1388 M_FCMPLT(s2, s1, REG_FTMP3);
1389 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1390 M_LADD_IMM(REG_ZERO, 1, d);
1392 M_LSUB_IMM(REG_ZERO, 1, d);
1393 M_FCMPEQS(s1, s2, REG_FTMP3);
1395 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1397 M_FCMPLTS(s2, s1, REG_FTMP3);
1399 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1400 M_LADD_IMM(REG_ZERO, 1, d);
1402 emit_store_dst(jd, iptr, d);
1405 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1407 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1408 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1409 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1411 M_LADD_IMM(REG_ZERO, 1, d);
1412 M_FCMPEQ(s1, s2, REG_FTMP3);
1413 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1415 M_FCMPLT(s1, s2, REG_FTMP3);
1416 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1417 M_LSUB_IMM(REG_ZERO, 1, d);
1419 M_LADD_IMM(REG_ZERO, 1, d);
1420 M_FCMPEQS(s1, s2, REG_FTMP3);
1422 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1424 M_FCMPLTS(s1, s2, REG_FTMP3);
1426 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1427 M_LSUB_IMM(REG_ZERO, 1, d);
1429 emit_store_dst(jd, iptr, d);
1433 /* memory operations **************************************************/
1435 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1437 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1438 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1439 emit_nullpointer_check(cd, iptr, s1);
1440 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1441 emit_store_dst(jd, iptr, d);
1444 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1447 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1448 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1449 emit_array_checks(cd, iptr, s1, s2);
1450 if (has_ext_instr_set) {
1451 M_LADD(s2, s1, REG_ITMP1);
1452 M_BLDU(d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1456 M_LADD(s2, s1, REG_ITMP1);
1457 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1458 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1459 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1460 M_SRA_IMM(d, 56, d);
1462 emit_store_dst(jd, iptr, d);
1465 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1468 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1469 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1470 emit_array_checks(cd, iptr, s1, s2);
1471 if (has_ext_instr_set) {
1472 M_LADD(s2, s1, REG_ITMP1);
1473 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1474 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1477 M_LADD (s2, s1, REG_ITMP1);
1478 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1479 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1480 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1481 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1483 emit_store_dst(jd, iptr, d);
1486 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1488 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1489 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1490 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1491 emit_array_checks(cd, iptr, s1, s2);
1492 if (has_ext_instr_set) {
1493 M_LADD(s2, s1, REG_ITMP1);
1494 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1495 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1498 M_LADD(s2, s1, REG_ITMP1);
1499 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1500 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1501 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1502 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1503 M_SRA_IMM(d, 48, d);
1505 emit_store_dst(jd, iptr, d);
1508 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1510 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1511 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1512 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1513 emit_array_checks(cd, iptr, s1, s2);
1514 M_S4ADDQ(s2, s1, REG_ITMP1);
1515 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1516 emit_store_dst(jd, iptr, d);
1519 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1522 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1524 emit_array_checks(cd, iptr, s1, s2);
1525 M_S8ADDQ(s2, s1, REG_ITMP1);
1526 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1527 emit_store_dst(jd, iptr, d);
1530 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1532 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1533 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1534 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1535 emit_array_checks(cd, iptr, s1, s2);
1536 M_S4ADDQ(s2, s1, REG_ITMP1);
1537 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1538 emit_store_dst(jd, iptr, d);
1541 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1544 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1545 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1546 emit_array_checks(cd, iptr, s1, s2);
1547 M_S8ADDQ(s2, s1, REG_ITMP1);
1548 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1549 emit_store_dst(jd, iptr, d);
1552 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1555 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1557 emit_array_checks(cd, iptr, s1, s2);
1558 M_SAADDQ(s2, s1, REG_ITMP1);
1559 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1560 emit_store_dst(jd, iptr, d);
1564 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1568 emit_array_checks(cd, iptr, s1, s2);
1569 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1570 if (has_ext_instr_set) {
1571 M_LADD(s2, s1, REG_ITMP1);
1572 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1575 M_LADD(s2, s1, REG_ITMP1);
1576 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1577 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1578 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1579 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1580 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1581 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1585 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1588 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1589 emit_array_checks(cd, iptr, s1, s2);
1590 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1591 if (has_ext_instr_set) {
1592 M_LADD(s2, s1, REG_ITMP1);
1593 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1594 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1597 M_LADD(s2, s1, REG_ITMP1);
1598 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1599 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1600 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1601 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1602 M_MSKWL(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_SASTORE: /* ..., arrayref, index, value ==> ... */
1610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1611 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1612 emit_array_checks(cd, iptr, s1, s2);
1613 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1614 if (has_ext_instr_set) {
1615 M_LADD(s2, s1, REG_ITMP1);
1616 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1617 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1620 M_LADD(s2, s1, REG_ITMP1);
1621 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1622 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1623 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1624 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1625 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1626 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1627 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1631 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1633 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1634 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1635 emit_array_checks(cd, iptr, s1, s2);
1636 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1637 M_S4ADDQ(s2, s1, REG_ITMP1);
1638 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1641 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1643 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1644 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1645 emit_array_checks(cd, iptr, s1, s2);
1646 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1647 M_S8ADDQ(s2, s1, REG_ITMP1);
1648 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1651 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1653 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1654 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1655 emit_array_checks(cd, iptr, s1, s2);
1656 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1657 M_S4ADDQ(s2, s1, REG_ITMP1);
1658 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1661 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1664 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1665 emit_array_checks(cd, iptr, s1, s2);
1666 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1667 M_S8ADDQ(s2, s1, REG_ITMP1);
1668 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1671 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1673 s1 = emit_load_s1(jd, iptr, REG_A0);
1674 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1675 emit_array_checks(cd, iptr, s1, s2);
1676 s3 = emit_load_s3(jd, iptr, REG_A1);
1678 M_INTMOVE(s1, REG_A0);
1679 M_INTMOVE(s3, REG_A1);
1681 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1682 M_ALD(REG_PV, REG_PV, disp);
1683 M_JSR(REG_RA, REG_PV);
1684 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1685 M_LDA(REG_PV, REG_RA, -disp);
1687 M_BEQZ(REG_RESULT, 0);
1688 codegen_add_arraystoreexception_ref(cd);
1690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1691 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1692 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1693 M_SAADDQ(s2, s1, REG_ITMP1);
1694 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1698 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1701 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1702 emit_array_checks(cd, iptr, s1, s2);
1703 if (has_ext_instr_set) {
1704 M_LADD(s2, s1, REG_ITMP1);
1705 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1708 M_LADD(s2, s1, REG_ITMP1);
1709 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1710 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1711 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1712 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1713 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1714 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1718 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1721 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1722 emit_array_checks(cd, iptr, s1, s2);
1723 if (has_ext_instr_set) {
1724 M_LADD(s2, s1, REG_ITMP1);
1725 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1726 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1729 M_LADD(s2, s1, REG_ITMP1);
1730 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1731 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1732 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1733 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1734 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1735 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1736 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1740 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1744 emit_array_checks(cd, iptr, s1, s2);
1745 if (has_ext_instr_set) {
1746 M_LADD(s2, s1, REG_ITMP1);
1747 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1748 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1751 M_LADD(s2, s1, REG_ITMP1);
1752 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1753 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1754 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1755 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1756 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1757 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1758 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1762 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1765 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1766 emit_array_checks(cd, iptr, s1, s2);
1767 M_S4ADDQ(s2, s1, REG_ITMP1);
1768 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1771 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1774 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1775 emit_array_checks(cd, iptr, s1, s2);
1776 M_S8ADDQ(s2, s1, REG_ITMP1);
1777 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1780 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1783 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1784 emit_array_checks(cd, iptr, s1, s2);
1785 M_SAADDQ(s2, s1, REG_ITMP1);
1786 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1790 case ICMD_GETSTATIC: /* ... ==> ..., value */
1792 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1793 uf = iptr->sx.s23.s3.uf;
1794 fieldtype = uf->fieldref->parseddesc.fd->type;
1795 disp = dseg_add_unique_address(cd, uf);
1797 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1800 fi = iptr->sx.s23.s3.fmiref->p.field;
1801 fieldtype = fi->type;
1802 disp = dseg_add_address(cd, &(fi->value));
1804 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1805 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1809 M_ALD(REG_ITMP1, REG_PV, disp);
1810 switch (fieldtype) {
1812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1813 M_ILD(d, REG_ITMP1, 0);
1816 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1817 M_LLD(d, REG_ITMP1, 0);
1820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1821 M_ALD(d, REG_ITMP1, 0);
1824 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1825 M_FLD(d, REG_ITMP1, 0);
1828 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1829 M_DLD(d, REG_ITMP1, 0);
1832 emit_store_dst(jd, iptr, d);
1835 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1837 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1838 uf = iptr->sx.s23.s3.uf;
1839 fieldtype = uf->fieldref->parseddesc.fd->type;
1840 disp = dseg_add_unique_address(cd, uf);
1842 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1845 fi = iptr->sx.s23.s3.fmiref->p.field;
1846 fieldtype = fi->type;
1847 disp = dseg_add_address(cd, &(fi->value));
1849 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1850 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1854 M_ALD(REG_ITMP1, REG_PV, disp);
1855 switch (fieldtype) {
1857 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1858 M_IST(s1, REG_ITMP1, 0);
1861 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1862 M_LST(s1, REG_ITMP1, 0);
1865 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1866 M_AST(s1, REG_ITMP1, 0);
1869 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1870 M_FST(s1, REG_ITMP1, 0);
1873 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1874 M_DST(s1, REG_ITMP1, 0);
1879 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1880 /* val = value (in current instruction) */
1881 /* following NOP) */
1883 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1884 uf = iptr->sx.s23.s3.uf;
1885 fieldtype = uf->fieldref->parseddesc.fd->type;
1886 disp = dseg_add_unique_address(cd, uf);
1888 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1891 fi = iptr->sx.s23.s3.fmiref->p.field;
1892 fieldtype = fi->type;
1893 disp = dseg_add_address(cd, &(fi->value));
1895 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1896 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
1900 M_ALD(REG_ITMP1, REG_PV, disp);
1901 switch (fieldtype) {
1903 M_IST(REG_ZERO, REG_ITMP1, 0);
1906 M_LST(REG_ZERO, REG_ITMP1, 0);
1909 M_AST(REG_ZERO, REG_ITMP1, 0);
1912 M_FST(REG_ZERO, REG_ITMP1, 0);
1915 M_DST(REG_ZERO, REG_ITMP1, 0);
1921 case ICMD_GETFIELD: /* ... ==> ..., value */
1923 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1924 emit_nullpointer_check(cd, iptr, s1);
1926 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1927 uf = iptr->sx.s23.s3.uf;
1928 fieldtype = uf->fieldref->parseddesc.fd->type;
1931 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1934 fi = iptr->sx.s23.s3.fmiref->p.field;
1935 fieldtype = fi->type;
1939 switch (fieldtype) {
1941 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1945 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1953 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1957 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1961 emit_store_dst(jd, iptr, d);
1964 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1967 emit_nullpointer_check(cd, iptr, s1);
1969 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1970 uf = iptr->sx.s23.s3.uf;
1971 fieldtype = uf->fieldref->parseddesc.fd->type;
1976 fi = iptr->sx.s23.s3.fmiref->p.field;
1977 fieldtype = fi->type;
1981 if (IS_INT_LNG_TYPE(fieldtype))
1982 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1984 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1986 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1987 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1989 switch (fieldtype) {
1991 M_IST(s2, s1, disp);
1994 M_LST(s2, s1, disp);
1997 M_AST(s2, s1, disp);
2000 M_FST(s2, s1, disp);
2003 M_DST(s2, s1, disp);
2008 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2009 /* val = value (in current instruction) */
2010 /* following NOP) */
2012 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2013 emit_nullpointer_check(cd, iptr, s1);
2015 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2016 uf = iptr->sx.s23.s3.uf;
2017 fieldtype = uf->fieldref->parseddesc.fd->type;
2020 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2023 fi = iptr->sx.s23.s3.fmiref->p.field;
2024 fieldtype = fi->type;
2028 switch (fieldtype) {
2030 M_IST(REG_ZERO, s1, disp);
2033 M_LST(REG_ZERO, s1, disp);
2036 M_AST(REG_ZERO, s1, disp);
2039 M_FST(REG_ZERO, s1, disp);
2042 M_DST(REG_ZERO, s1, disp);
2048 /* branch operations **************************************************/
2050 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053 M_INTMOVE(s1, REG_ITMP1_XPTR);
2055 #ifdef ENABLE_VERIFIER
2056 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2057 unresolved_class *uc = iptr->sx.s23.s2.uc;
2059 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2061 #endif /* ENABLE_VERIFIER */
2063 disp = dseg_add_functionptr(cd, asm_handle_exception);
2064 M_ALD(REG_ITMP2, REG_PV, disp);
2065 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2066 M_NOP; /* nop ensures that XPC is less than the end */
2067 /* of basic block */
2071 case ICMD_GOTO: /* ... ==> ... */
2072 case ICMD_RET: /* ... ==> ... */
2075 codegen_add_branch_ref(cd, iptr->dst.block);
2079 case ICMD_JSR: /* ... ==> ... */
2082 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2086 case ICMD_IFNULL: /* ..., value ==> ... */
2088 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2090 codegen_add_branch_ref(cd, iptr->dst.block);
2093 case ICMD_IFNONNULL: /* ..., value ==> ... */
2095 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2097 codegen_add_branch_ref(cd, iptr->dst.block);
2100 case ICMD_IFEQ: /* ..., value ==> ... */
2102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2103 if (iptr->sx.val.i == 0) {
2107 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2108 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2111 ICONST(REG_ITMP2, iptr->sx.val.i);
2112 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2114 M_BNEZ(REG_ITMP1, 0);
2116 codegen_add_branch_ref(cd, iptr->dst.block);
2119 case ICMD_IFLT: /* ..., value ==> ... */
2121 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2122 if (iptr->sx.val.i == 0) {
2126 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2127 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2130 ICONST(REG_ITMP2, iptr->sx.val.i);
2131 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2133 M_BNEZ(REG_ITMP1, 0);
2135 codegen_add_branch_ref(cd, iptr->dst.block);
2138 case ICMD_IFLE: /* ..., value ==> ... */
2140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141 if (iptr->sx.val.i == 0) {
2145 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2146 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2149 ICONST(REG_ITMP2, iptr->sx.val.i);
2150 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2152 M_BNEZ(REG_ITMP1, 0);
2154 codegen_add_branch_ref(cd, iptr->dst.block);
2157 case ICMD_IFNE: /* ..., value ==> ... */
2159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2160 if (iptr->sx.val.i == 0) {
2164 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2165 M_CMPEQ_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2168 ICONST(REG_ITMP2, iptr->sx.val.i);
2169 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2171 M_BEQZ(REG_ITMP1, 0);
2173 codegen_add_branch_ref(cd, iptr->dst.block);
2176 case ICMD_IFGT: /* ..., value ==> ... */
2178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2179 if (iptr->sx.val.i == 0) {
2183 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2184 M_CMPLE_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2187 ICONST(REG_ITMP2, iptr->sx.val.i);
2188 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2190 M_BEQZ(REG_ITMP1, 0);
2192 codegen_add_branch_ref(cd, iptr->dst.block);
2195 case ICMD_IFGE: /* ..., value ==> ... */
2197 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2198 if (iptr->sx.val.i == 0) {
2202 if ((iptr->sx.val.i > 0) && (iptr->sx.val.i <= 255)) {
2203 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2206 ICONST(REG_ITMP2, iptr->sx.val.i);
2207 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2209 M_BEQZ(REG_ITMP1, 0);
2211 codegen_add_branch_ref(cd, iptr->dst.block);
2214 case ICMD_IF_LEQ: /* ..., value ==> ... */
2216 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2217 if (iptr->sx.val.l == 0) {
2221 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2222 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2225 LCONST(REG_ITMP2, iptr->sx.val.l);
2226 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2228 M_BNEZ(REG_ITMP1, 0);
2230 codegen_add_branch_ref(cd, iptr->dst.block);
2233 case ICMD_IF_LLT: /* ..., value ==> ... */
2235 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2236 if (iptr->sx.val.l == 0) {
2240 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2241 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2244 LCONST(REG_ITMP2, iptr->sx.val.l);
2245 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2247 M_BNEZ(REG_ITMP1, 0);
2249 codegen_add_branch_ref(cd, iptr->dst.block);
2252 case ICMD_IF_LLE: /* ..., value ==> ... */
2254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2255 if (iptr->sx.val.l == 0) {
2259 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2260 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2263 LCONST(REG_ITMP2, iptr->sx.val.l);
2264 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2266 M_BNEZ(REG_ITMP1, 0);
2268 codegen_add_branch_ref(cd, iptr->dst.block);
2271 case ICMD_IF_LNE: /* ..., value ==> ... */
2273 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2274 if (iptr->sx.val.l == 0) {
2278 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2279 M_CMPEQ_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2282 LCONST(REG_ITMP2, iptr->sx.val.l);
2283 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2285 M_BEQZ(REG_ITMP1, 0);
2287 codegen_add_branch_ref(cd, iptr->dst.block);
2290 case ICMD_IF_LGT: /* ..., value ==> ... */
2292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2293 if (iptr->sx.val.l == 0) {
2297 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2298 M_CMPLE_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2301 LCONST(REG_ITMP2, iptr->sx.val.l);
2302 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2304 M_BEQZ(REG_ITMP1, 0);
2306 codegen_add_branch_ref(cd, iptr->dst.block);
2309 case ICMD_IF_LGE: /* ..., value ==> ... */
2311 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2312 if (iptr->sx.val.l == 0) {
2316 if ((iptr->sx.val.l > 0) && (iptr->sx.val.l <= 255)) {
2317 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2320 LCONST(REG_ITMP2, iptr->sx.val.l);
2321 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2323 M_BEQZ(REG_ITMP1, 0);
2325 codegen_add_branch_ref(cd, iptr->dst.block);
2328 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2329 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2330 case ICMD_IF_ACMPEQ:
2332 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2333 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2334 M_CMPEQ(s1, s2, REG_ITMP1);
2335 M_BNEZ(REG_ITMP1, 0);
2336 codegen_add_branch_ref(cd, iptr->dst.block);
2339 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2340 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2341 case ICMD_IF_ACMPNE:
2343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2344 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2345 M_CMPEQ(s1, s2, REG_ITMP1);
2346 M_BEQZ(REG_ITMP1, 0);
2347 codegen_add_branch_ref(cd, iptr->dst.block);
2350 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2351 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2354 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2355 M_CMPLT(s1, s2, REG_ITMP1);
2356 M_BNEZ(REG_ITMP1, 0);
2357 codegen_add_branch_ref(cd, iptr->dst.block);
2360 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2361 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2364 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2365 M_CMPLE(s1, s2, REG_ITMP1);
2366 M_BEQZ(REG_ITMP1, 0);
2367 codegen_add_branch_ref(cd, iptr->dst.block);
2370 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2371 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2373 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2374 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2375 M_CMPLE(s1, s2, REG_ITMP1);
2376 M_BNEZ(REG_ITMP1, 0);
2377 codegen_add_branch_ref(cd, iptr->dst.block);
2380 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2381 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2383 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2384 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2385 M_CMPLT(s1, s2, REG_ITMP1);
2386 M_BEQZ(REG_ITMP1, 0);
2387 codegen_add_branch_ref(cd, iptr->dst.block);
2391 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2394 REPLACEMENT_POINT_RETURN(cd, iptr);
2395 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2396 M_INTMOVE(s1, REG_RESULT);
2397 goto nowperformreturn;
2399 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2401 REPLACEMENT_POINT_RETURN(cd, iptr);
2402 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2403 M_INTMOVE(s1, REG_RESULT);
2405 #ifdef ENABLE_VERIFIER
2406 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2407 unresolved_class *uc = iptr->sx.s23.s2.uc;
2409 codegen_add_patch_ref(cd, PATCHER_resolve_class, uc, 0);
2411 #endif /* ENABLE_VERIFIER */
2412 goto nowperformreturn;
2414 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2417 REPLACEMENT_POINT_RETURN(cd, iptr);
2418 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2419 M_FLTMOVE(s1, REG_FRESULT);
2420 goto nowperformreturn;
2422 case ICMD_RETURN: /* ... ==> ... */
2424 REPLACEMENT_POINT_RETURN(cd, iptr);
2430 p = cd->stackframesize;
2432 /* call trace function */
2434 #if !defined(NDEBUG)
2435 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2436 emit_verbosecall_exit(jd);
2439 #if defined(ENABLE_THREADS)
2440 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2441 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2443 switch (iptr->opc) {
2447 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2451 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2455 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2456 M_ALD(REG_PV, REG_PV, disp);
2457 M_JSR(REG_RA, REG_PV);
2458 disp = -(s4) (cd->mcodeptr - cd->mcodebase);
2459 M_LDA(REG_PV, REG_RA, disp);
2461 switch (iptr->opc) {
2465 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2469 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2475 /* restore return address */
2477 if (!jd->isleafmethod) {
2478 p--; M_LLD(REG_RA, REG_SP, p * 8);
2481 /* restore saved registers */
2483 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2484 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2486 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2487 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2490 /* deallocate stack */
2492 if (cd->stackframesize)
2493 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
2495 M_RET(REG_ZERO, REG_RA);
2501 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2504 branch_target_t *table;
2506 table = iptr->dst.table;
2508 l = iptr->sx.s23.s2.tablelow;
2509 i = iptr->sx.s23.s3.tablehigh;
2511 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2513 M_INTMOVE(s1, REG_ITMP1);
2514 } else if (l <= 32768) {
2515 M_LDA(REG_ITMP1, s1, -l);
2517 ICONST(REG_ITMP2, l);
2518 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2521 /* number of targets */
2527 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
2529 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
2530 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
2532 M_BEQZ(REG_ITMP2, 0);
2533 codegen_add_branch_ref(cd, table[0].block);
2535 /* build jump table top down and use address of lowest entry */
2540 dseg_add_target(cd, table->block);
2545 /* length of dataseg after last dseg_add_target is used by load */
2547 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
2548 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2549 M_JMP(REG_ZERO, REG_ITMP2);
2554 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2557 lookup_target_t *lookup;
2559 lookup = iptr->dst.lookup;
2561 i = iptr->sx.s23.s2.lookupcount;
2563 MCODECHECK((i<<2)+8);
2564 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2567 val = lookup->value;
2568 if ((val >= 0) && (val <= 255)) {
2569 M_CMPEQ_IMM(s1, val, REG_ITMP2);
2571 if ((val >= -32768) && (val <= 32767)) {
2572 M_LDA(REG_ITMP2, REG_ZERO, val);
2574 disp = dseg_add_s4(cd, val);
2575 M_ILD(REG_ITMP2, REG_PV, disp);
2577 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
2579 M_BNEZ(REG_ITMP2, 0);
2580 codegen_add_branch_ref(cd, lookup->target.block);
2586 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2593 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2595 bte = iptr->sx.s23.s3.bte;
2599 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2601 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2602 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2603 case ICMD_INVOKEINTERFACE:
2605 REPLACEMENT_POINT_INVOKE(cd, iptr);
2607 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2609 um = iptr->sx.s23.s3.um;
2610 md = um->methodref->parseddesc.md;
2613 lm = iptr->sx.s23.s3.fmiref->p.method;
2615 md = lm->parseddesc;
2619 s3 = md->paramcount;
2621 MCODECHECK((s3 << 1) + 64);
2623 /* copy arguments to registers or stack location */
2625 for (s3 = s3 - 1; s3 >= 0; s3--) {
2626 var = VAR(iptr->sx.s23.s2.args[s3]);
2628 /* Already Preallocated (ARGVAR) ? */
2629 if (var->flags & PREALLOC)
2632 if (IS_INT_LNG_TYPE(var->type)) {
2633 if (!md->params[s3].inmemory) {
2634 s1 = rd->argintregs[md->params[s3].regoff];
2635 d = emit_load(jd, iptr, var, s1);
2639 d = emit_load(jd, iptr, var, REG_ITMP1);
2640 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2644 if (!md->params[s3].inmemory) {
2645 s1 = rd->argfltregs[md->params[s3].regoff];
2646 d = emit_load(jd, iptr, var, s1);
2650 d = emit_load(jd, iptr, var, REG_FTMP1);
2651 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2656 switch (iptr->opc) {
2658 disp = dseg_add_functionptr(cd, bte->fp);
2660 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
2663 case ICMD_INVOKESPECIAL:
2665 codegen_add_nullpointerexception_ref(cd);
2668 case ICMD_INVOKESTATIC:
2670 disp = dseg_add_unique_address(cd, um);
2672 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2676 disp = dseg_add_address(cd, lm->stubroutine);
2678 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
2681 case ICMD_INVOKEVIRTUAL:
2682 emit_nullpointer_check(cd, iptr, REG_A0);
2685 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2690 s1 = OFFSET(vftbl_t, table[0]) +
2691 sizeof(methodptr) * lm->vftblindex;
2693 M_ALD(REG_METHODPTR, REG_A0,
2694 OFFSET(java_objectheader, vftbl));
2695 M_ALD(REG_PV, REG_METHODPTR, s1);
2698 case ICMD_INVOKEINTERFACE:
2699 emit_nullpointer_check(cd, iptr, REG_A0);
2702 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2708 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2709 sizeof(methodptr*) * lm->class->index;
2711 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2714 M_ALD(REG_METHODPTR, REG_A0,
2715 OFFSET(java_objectheader, vftbl));
2716 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2717 M_ALD(REG_PV, REG_METHODPTR, s2);
2721 /* generate the actual call */
2723 M_JSR(REG_RA, REG_PV);
2724 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
2725 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2726 M_LDA(REG_PV, REG_RA, -disp);
2728 /* actually only used for ICMD_BUILTIN */
2730 if (INSTRUCTION_MUST_CHECK(iptr)) {
2731 M_BEQZ(REG_RESULT, 0);
2732 codegen_add_fillinstacktrace_ref(cd);
2735 /* store the return value */
2737 d = md->returntype.type;
2739 if (d != TYPE_VOID) {
2740 if (IS_INT_LNG_TYPE(d)) {
2741 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2742 M_INTMOVE(REG_RESULT, s1);
2745 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2746 M_FLTMOVE(REG_FRESULT, s1);
2748 emit_store_dst(jd, iptr, s1);
2753 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2755 /* val.a: (classinfo*) superclass */
2757 /* superclass is an interface:
2759 * OK if ((sub == NULL) ||
2760 * (sub->vftbl->interfacetablelength > super->index) &&
2761 * (sub->vftbl->interfacetable[-super->index] != NULL));
2763 * superclass is a class:
2765 * OK if ((sub == NULL) || (0
2766 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2767 * super->vftbl->diffval));
2770 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2771 /* object type cast-check */
2774 vftbl_t *supervftbl;
2777 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2783 super = iptr->sx.s23.s3.c.cls;
2784 superindex = super->index;
2785 supervftbl = super->vftbl;
2788 #if defined(ENABLE_THREADS)
2789 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2793 /* calculate interface checkcast code size */
2797 s2 += opt_shownops ? 1 : 0;
2799 /* calculate class checkcast code size */
2801 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
2803 s3 += opt_shownops ? 1 : 0;
2805 /* if class is not resolved, check which code to call */
2807 if (super == NULL) {
2808 M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
2810 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2812 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2813 iptr->sx.s23.s3.c.ref,
2816 M_ILD(REG_ITMP2, REG_PV, disp);
2817 disp = dseg_add_s4(cd, ACC_INTERFACE);
2818 M_ILD(REG_ITMP3, REG_PV, disp);
2819 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2820 M_BEQZ(REG_ITMP2, s2 + 1);
2823 /* interface checkcast code */
2825 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2826 if (super == NULL) {
2827 codegen_add_patch_ref(cd,
2828 PATCHER_checkcast_instanceof_interface,
2829 iptr->sx.s23.s3.c.ref,
2835 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2836 M_ILD(REG_ITMP3, REG_ITMP2,
2837 OFFSET(vftbl_t, interfacetablelength));
2838 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2839 M_BLEZ(REG_ITMP3, 0);
2840 codegen_add_classcastexception_ref(cd, s1);
2841 M_ALD(REG_ITMP3, REG_ITMP2,
2842 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2843 superindex * sizeof(methodptr*)));
2844 M_BEQZ(REG_ITMP3, 0);
2845 codegen_add_classcastexception_ref(cd, s1);
2851 /* class checkcast code */
2853 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2854 if (super == NULL) {
2855 disp = dseg_add_unique_address(cd, NULL);
2857 codegen_add_patch_ref(cd,
2858 PATCHER_resolve_classref_to_vftbl,
2859 iptr->sx.s23.s3.c.ref,
2863 disp = dseg_add_address(cd, supervftbl);
2868 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2869 M_ALD(REG_ITMP3, REG_PV, disp);
2870 #if defined(ENABLE_THREADS)
2871 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2873 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2874 /* if (s1 != REG_ITMP1) { */
2875 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2876 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2877 /* #if defined(ENABLE_THREADS) */
2878 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2880 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2883 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2884 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2885 M_ALD(REG_ITMP3, REG_PV, disp);
2886 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2887 #if defined(ENABLE_THREADS)
2888 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2891 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2892 M_BEQZ(REG_ITMP3, 0);
2893 codegen_add_classcastexception_ref(cd, s1);
2896 d = codegen_reg_of_dst(jd, iptr, s1);
2899 /* array type cast-check */
2901 s1 = emit_load_s1(jd, iptr, REG_A0);
2902 M_INTMOVE(s1, REG_A0);
2904 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2905 disp = dseg_add_unique_address(cd, NULL);
2907 codegen_add_patch_ref(cd,
2908 PATCHER_resolve_classref_to_classinfo,
2909 iptr->sx.s23.s3.c.ref,
2913 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2915 M_ALD(REG_A1, REG_PV, disp);
2916 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2917 M_ALD(REG_PV, REG_PV, disp);
2918 M_JSR(REG_RA, REG_PV);
2919 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2920 M_LDA(REG_PV, REG_RA, -disp);
2922 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2923 M_BEQZ(REG_RESULT, 0);
2924 codegen_add_classcastexception_ref(cd, s1);
2926 d = codegen_reg_of_dst(jd, iptr, s1);
2930 emit_store_dst(jd, iptr, d);
2933 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2935 /* val.a: (classinfo*) superclass */
2937 /* superclass is an interface:
2939 * return (sub != NULL) &&
2940 * (sub->vftbl->interfacetablelength > super->index) &&
2941 * (sub->vftbl->interfacetable[-super->index] != NULL);
2943 * superclass is a class:
2945 * return ((sub != NULL) && (0
2946 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2947 * super->vftbl->diffvall));
2952 vftbl_t *supervftbl;
2955 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2961 super = iptr->sx.s23.s3.c.cls;
2962 superindex = super->index;
2963 supervftbl = super->vftbl;
2966 #if defined(ENABLE_THREADS)
2967 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2969 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2970 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2972 M_MOV(s1, REG_ITMP1);
2976 /* calculate interface instanceof code size */
2980 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_shownops ? 1 : 0);
2982 /* calculate class instanceof code size */
2986 s3 += (opt_shownops ? 1 : 0);
2988 /* if class is not resolved, check which code to call */
2990 if (super == NULL) {
2992 M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
2994 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2996 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
2997 iptr->sx.s23.s3.c.ref, disp);
2999 M_ILD(REG_ITMP3, REG_PV, disp);
3001 disp = dseg_add_s4(cd, ACC_INTERFACE);
3002 M_ILD(REG_ITMP2, REG_PV, disp);
3003 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3004 M_BEQZ(REG_ITMP3, s2 + 1);
3007 /* interface instanceof code */
3009 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3010 if (super == NULL) {
3011 /* If d == REG_ITMP2, then it's destroyed in check
3016 codegen_add_patch_ref(cd,
3017 PATCHER_checkcast_instanceof_interface,
3018 iptr->sx.s23.s3.c.ref, 0);
3025 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3026 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3027 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3028 M_BLEZ(REG_ITMP3, 2);
3029 M_ALD(REG_ITMP1, REG_ITMP1,
3030 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3031 superindex * sizeof(methodptr*)));
3032 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3038 /* class instanceof code */
3040 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3041 if (super == NULL) {
3042 disp = dseg_add_unique_address(cd, NULL);
3044 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3045 iptr->sx.s23.s3.c.ref,
3049 disp = dseg_add_address(cd, supervftbl);
3055 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3056 M_ALD(REG_ITMP2, REG_PV, disp);
3057 #if defined(ENABLE_THREADS)
3058 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3060 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3061 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3062 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3063 #if defined(ENABLE_THREADS)
3064 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3066 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3067 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3069 emit_store_dst(jd, iptr, d);
3073 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3075 /* check for negative sizes and copy sizes to stack if necessary */
3077 MCODECHECK((iptr->s1.argcount << 1) + 64);
3079 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3081 var = VAR(iptr->sx.s23.s2.args[s1]);
3083 /* copy SAVEDVAR sizes to stack */
3085 /* Already Preallocated? */
3087 if (!(var->flags & PREALLOC)) {
3088 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3089 M_LST(s2, REG_SP, s1 * 8);
3093 /* a0 = dimension count */
3095 ICONST(REG_A0, iptr->s1.argcount);
3097 /* is patcher function set? */
3099 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3100 disp = dseg_add_unique_address(cd, 0);
3102 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
3103 iptr->sx.s23.s3.c.ref,
3107 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3109 /* a1 = arraydescriptor */
3111 M_ALD(REG_A1, REG_PV, disp);
3113 /* a2 = pointer to dimensions = stack pointer */
3115 M_INTMOVE(REG_SP, REG_A2);
3117 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3118 M_ALD(REG_PV, REG_PV, disp);
3119 M_JSR(REG_RA, REG_PV);
3120 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3121 M_LDA(REG_PV, REG_RA, -disp);
3123 /* check for exception before result assignment */
3125 M_BEQZ(REG_RESULT, 0);
3126 codegen_add_fillinstacktrace_ref(cd);
3128 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3129 M_INTMOVE(REG_RESULT, d);
3130 emit_store_dst(jd, iptr, d);
3135 new_internalerror("Unknown ICMD %d", iptr->opc);
3139 } /* for instruction */
3141 } /* if (bptr -> flags >= BBREACHED) */
3142 } /* for basic block */
3144 dseg_createlinenumbertable(cd);
3146 /* generate stubs */
3148 emit_exception_stubs(jd);
3149 emit_patcher_stubs(jd);
3150 REPLACEMENT_EMIT_STUBS(jd);
3154 /* everything's ok */
3160 /* createcompilerstub **********************************************************
3162 Creates a stub routine which calls the compiler.
3164 *******************************************************************************/
3166 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3167 #define COMPILERSTUB_CODESIZE 3 * 4
3169 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3172 u1 *createcompilerstub(methodinfo *m)
3174 u1 *s; /* memory to hold the stub */
3177 s4 dumpsize; /* code generation pointer */
3179 s = CNEW(u1, COMPILERSTUB_SIZE);
3181 /* set data pointer and code pointer */
3184 s = s + COMPILERSTUB_DATASIZE;
3186 /* mark start of dump memory area */
3188 dumpsize = dump_size();
3190 cd = DNEW(codegendata);
3193 /* The codeinfo pointer is actually a pointer to the
3194 methodinfo. This fakes a codeinfo structure. */
3196 d[0] = (ptrint) asm_call_jit_compiler;
3198 d[2] = (ptrint) &d[1]; /* fake code->m */
3200 /* code for the stub */
3202 M_ALD(REG_ITMP1, REG_PV, -2 * 8); /* load codeinfo pointer */
3203 M_ALD(REG_PV, REG_PV, -3 * 8); /* load pointer to the compiler */
3204 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3206 #if defined(ENABLE_STATISTICS)
3208 count_cstub_len += COMPILERSTUB_SIZE;
3211 /* release dump area */
3213 dump_release(dumpsize);
3219 /* createnativestub ************************************************************
3221 Creates a stub routine which calls a native method.
3223 *******************************************************************************/
3225 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3233 s4 i, j; /* count variables */
3236 s4 funcdisp; /* displacement of the function */
3238 /* get required compiler data */
3245 /* initialize variables */
3248 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3250 /* calculate stack frame size */
3252 cd->stackframesize =
3253 1 + /* return address */
3254 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3255 sizeof(localref_table) / SIZEOF_VOID_P +
3256 1 + /* methodinfo for call trace */
3257 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
3260 /* create method header */
3262 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3263 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3264 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3265 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3266 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3267 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3268 (void) dseg_addlinenumbertablesize(cd);
3269 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3271 /* generate stub code */
3273 M_LDA(REG_SP, REG_SP, -(cd->stackframesize * 8));
3274 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3276 /* call trace function */
3278 #if !defined(NDEBUG)
3279 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3280 emit_verbosecall_enter(jd);
3283 /* get function address (this must happen before the stackframeinfo) */
3285 funcdisp = dseg_add_functionptr(cd, f);
3287 #if !defined(WITH_STATIC_CLASSPATH)
3289 codegen_add_patch_ref(cd, PATCHER_resolve_native_function, m, funcdisp);
3292 /* save integer and float argument registers */
3294 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3295 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3296 M_LST(rd->argintregs[i], REG_SP, j * 8);
3301 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3302 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3303 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3308 /* prepare data structures for native function call */
3310 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3311 M_MOV(REG_PV, REG_A1);
3312 M_LDA(REG_A2, REG_SP, cd->stackframesize * 8);
3313 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3314 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3315 M_ALD(REG_PV, REG_PV, disp);
3316 M_JSR(REG_RA, REG_PV);
3317 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3318 M_LDA(REG_PV, REG_RA, -disp);
3320 /* restore integer and float argument registers */
3322 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3323 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3324 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3329 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3330 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3331 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3336 /* copy or spill arguments to new locations */
3338 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3339 t = md->paramtypes[i].type;
3341 if (IS_INT_LNG_TYPE(t)) {
3342 if (!md->params[i].inmemory) {
3343 s1 = rd->argintregs[md->params[i].regoff];
3345 if (!nmd->params[j].inmemory) {
3346 s2 = rd->argintregs[nmd->params[j].regoff];
3350 s2 = nmd->params[j].regoff;
3351 M_LST(s1, REG_SP, s2 * 8);
3355 s1 = md->params[i].regoff + cd->stackframesize;
3356 s2 = nmd->params[j].regoff;
3357 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3358 M_LST(REG_ITMP1, REG_SP, s2 * 8);
3362 if (!md->params[i].inmemory) {
3363 s1 = rd->argfltregs[md->params[i].regoff];
3365 if (!nmd->params[j].inmemory) {
3366 s2 = rd->argfltregs[nmd->params[j].regoff];
3370 s2 = nmd->params[j].regoff;
3371 if (IS_2_WORD_TYPE(t))
3372 M_DST(s1, REG_SP, s2 * 8);
3374 M_FST(s1, REG_SP, s2 * 8);
3378 s1 = md->params[i].regoff + cd->stackframesize;
3379 s2 = nmd->params[j].regoff;
3380 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3381 if (IS_2_WORD_TYPE(t))
3382 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3384 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3389 /* put class into second argument register */
3391 if (m->flags & ACC_STATIC) {
3392 disp = dseg_add_address(cd, m->class);
3393 M_ALD(REG_A1, REG_PV, disp);
3396 /* put env into first argument register */
3398 disp = dseg_add_address(cd, _Jv_env);
3399 M_ALD(REG_A0, REG_PV, disp);
3401 /* do the native function call */
3403 M_ALD(REG_PV, REG_PV, funcdisp);
3404 M_JSR(REG_RA, REG_PV); /* call native method */
3405 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3406 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
3408 /* save return value */
3410 if (md->returntype.type != TYPE_VOID) {
3411 if (IS_INT_LNG_TYPE(md->returntype.type))
3412 M_LST(REG_RESULT, REG_SP, 0 * 8);
3414 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3417 /* call finished trace */
3419 #if !defined(NDEBUG)
3420 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3421 emit_verbosecall_exit(jd);
3424 /* remove native stackframe info */
3426 M_LDA(REG_A0, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3427 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3428 M_ALD(REG_PV, REG_PV, disp);
3429 M_JSR(REG_RA, REG_PV);
3430 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3431 M_LDA(REG_PV, REG_RA, -disp);
3432 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3434 /* restore return value */
3436 if (md->returntype.type != TYPE_VOID) {
3437 if (IS_INT_LNG_TYPE(md->returntype.type))
3438 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3440 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3443 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* get RA */
3444 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8);
3446 /* check for exception */
3448 M_BNEZ(REG_ITMP1_XPTR, 1); /* if no exception then return */
3449 M_RET(REG_ZERO, REG_RA); /* return to caller */
3451 /* handle exception */
3453 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address */
3455 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3456 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3457 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
3460 /* generate patcher stubs */
3462 emit_patcher_stubs(jd);
3466 return code->entrypoint;
3471 * These are local overrides for various environment variables in Emacs.
3472 * Please do not remove this and leave it at the end of the file, where
3473 * Emacs will automagically detect them.
3474 * ---------------------------------------------------------------------
3477 * indent-tabs-mode: t
3481 * vim:noexpandtab:sw=4:ts=4: