1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
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: Christian Thalinger
34 Contains the codegenerator for an MIPS (R4000 or higher) processor.
35 This module generates MIPS machine code for a sequence of
36 intermediate code commands (ICMDs).
38 $Id: codegen.c 5388 2006-09-06 22:34:46Z twisti $
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
56 #include "native/native.h"
58 #if defined(ENABLE_THREADS)
59 # include "threads/native/lock.h"
62 #include "vm/builtin.h"
64 #include "vm/exceptions.h"
65 #include "vm/options.h"
66 #include "vm/stringlocal.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/codegen-common.h"
70 #include "vm/jit/dseg.h"
71 #include "vm/jit/emit.h"
72 #include "vm/jit/jit.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;
102 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
103 unresolved_method *um;
104 builtintable_entry *bte;
106 rplpoint *replacementpoint;
109 /* get required compiler data */
120 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
122 /* space to save used callee saved registers */
124 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
125 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
127 cd->stackframesize = rd->memuse + savedregs_num;
129 #if defined(ENABLE_THREADS)
130 /* space to save argument of monitor_enter */
132 if (checksync && (m->flags & ACC_SYNCHRONIZED))
133 cd->stackframesize++;
136 /* keep stack 16-byte aligned */
138 if (cd->stackframesize & 1)
139 cd->stackframesize++;
141 /* create method header */
143 #if SIZEOF_VOID_P == 4
144 (void) dseg_addaddress(cd, code); /* Filler */
146 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
147 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
149 #if defined(ENABLE_THREADS)
150 /* IsSync contains the offset relative to the stack pointer for the
151 argument of monitor_exit used in the exception handler. Since the
152 offset could be zero and give a wrong meaning of the flag it is
156 if (checksync && (m->flags & ACC_SYNCHRONIZED))
157 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
160 (void) dseg_adds4(cd, 0); /* IsSync */
162 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
163 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
164 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
165 dseg_addlinenumbertablesize(cd);
166 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
168 /* create exception table */
170 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
171 dseg_addtarget(cd, ex->start);
172 dseg_addtarget(cd, ex->end);
173 dseg_addtarget(cd, ex->handler);
174 (void) dseg_addaddress(cd, ex->catchtype.cls);
177 /* create stack frame (if necessary) */
179 if (cd->stackframesize)
180 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
182 /* save return address and used callee saved registers */
184 p = cd->stackframesize;
185 if (!jd->isleafmethod) {
186 p--; M_AST(REG_RA, REG_SP, p * 8);
188 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
189 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
191 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
192 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
195 /* take arguments out of register or stack frame */
199 for (p = 0, l = 0; p < md->paramcount; p++) {
200 t = md->paramtypes[p].type;
201 var = &(rd->locals[l][t]);
203 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
207 s1 = md->params[p].regoff;
208 if (IS_INT_LNG_TYPE(t)) { /* integer args */
209 if (!md->params[p].inmemory) { /* register arguments */
210 s2 = rd->argintregs[s1];
211 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
212 M_INTMOVE(s2, var->regoff);
213 } else { /* reg arg -> spilled */
214 M_LST(s2, REG_SP, var->regoff * 8);
217 } else { /* stack arguments */
218 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
219 M_LLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
220 } else { /* stack arg -> spilled */
221 var->regoff = cd->stackframesize + s1;
225 } else { /* floating args */
226 if (!md->params[p].inmemory) { /* register arguments */
227 s2 = rd->argfltregs[s1];
228 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
229 if (IS_2_WORD_TYPE(t))
230 M_DMOV(s2, var->regoff);
232 M_FMOV(s2, var->regoff);
233 } else { /* reg arg -> spilled */
234 if (IS_2_WORD_TYPE(t))
235 M_DST(s2, REG_SP, var->regoff * 8);
237 M_FST(s2, REG_SP, var->regoff * 8);
240 } else { /* stack arguments */
241 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
242 if (IS_2_WORD_TYPE(t))
243 M_DLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
245 M_FLD(var->regoff, REG_SP, (cd->stackframesize + s1) * 8);
246 } else /* stack-arg -> spilled */
247 var->regoff = cd->stackframesize + s1;
252 /* call monitorenter function */
254 #if defined(ENABLE_THREADS)
255 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
256 /* stack offset for monitor argument */
260 # if !defined(NDEBUG)
261 if (opt_verbosecall) {
262 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
264 for (p = 0; p < INT_ARG_CNT; p++)
265 M_LST(rd->argintregs[p], REG_SP, p * 8);
267 for (p = 0; p < FLT_ARG_CNT; p++)
268 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
270 s1 += INT_ARG_CNT + FLT_ARG_CNT;
274 /* get correct lock object */
276 if (m->flags & ACC_STATIC) {
277 p = dseg_addaddress(cd, &m->class->object.header);
278 M_ALD(REG_A0, REG_PV, p);
282 codegen_add_nullpointerexception_ref(cd);
285 p = dseg_addaddress(cd, LOCK_monitor_enter);
286 M_ALD(REG_ITMP3, REG_PV, p);
287 M_JSR(REG_RA, REG_ITMP3);
288 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
290 # if !defined(NDEBUG)
291 if (opt_verbosecall) {
292 for (p = 0; p < INT_ARG_CNT; p++)
293 M_LLD(rd->argintregs[p], REG_SP, p * 8);
295 for (p = 0; p < FLT_ARG_CNT; p++)
296 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
299 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
306 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
307 emit_verbosecall_enter(jd);
312 /* end of header generation */
314 replacementpoint = jd->code->rplpoints;
316 /* walk through all basic blocks */
318 for (bptr = jd->new_basicblocks; bptr != NULL; bptr = bptr->next) {
320 /* handle replacement points */
323 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
325 /* 8-byte align pc */
326 if ((ptrint) cd->mcodeptr & 4) {
330 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
333 assert(cd->lastmcodeptr <= cd->mcodeptr);
334 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
338 /* store relative start of block */
340 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
342 if (bptr->flags >= BBREACHED) {
344 /* branch resolving */
347 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
348 gen_resolvebranch(cd->mcodebase + bref->branchpos,
354 /* copy interface registers to their destination */
358 #if defined(ENABLE_LSRA)
362 src = bptr->invars[len];
363 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
364 /* d = reg_of_var(m, src, REG_ITMP1); */
365 if (!(src->flags & INMEMORY))
369 M_INTMOVE(REG_ITMP1, d);
370 emit_store(jd, NULL, src, d);
377 src = bptr->invars[len];
378 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
379 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
380 M_INTMOVE(REG_ITMP1, d);
381 emit_store(jd, NULL, src, d);
384 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
385 if ((src->varkind != STACKVAR)) {
387 s1 = rd->interfaces[len][s2].regoff;
388 if (IS_FLT_DBL_TYPE(s2)) {
389 if (rd->interfaces[len][s2].flags & INMEMORY) {
390 if (IS_2_WORD_TYPE(s2))
391 M_DLD(d, REG_SP, s1 * 8);
393 M_FLD(d, REG_SP, s1 * 8);
396 if (IS_2_WORD_TYPE(s2))
403 if (rd->interfaces[len][s2].flags & INMEMORY)
404 M_LLD(d, REG_SP, s1 * 8);
409 emit_store(jd, NULL, src, d);
413 #if defined(ENABLE_LSRA)
416 /* walk through all instructions */
421 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
422 if (iptr->line != currentline) {
423 dseg_addlinenumber(cd, iptr->line);
424 currentline = iptr->line;
427 MCODECHECK(64); /* an instruction usually needs < 64 words */
431 case ICMD_NOP: /* ... ==> ... */
434 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
436 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
438 codegen_add_nullpointerexception_ref(cd);
442 /* constant operations ************************************************/
444 case ICMD_ICONST: /* ... ==> ..., constant */
446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
447 ICONST(d, iptr->sx.val.i);
448 emit_store_dst(jd, iptr, d);
451 case ICMD_LCONST: /* ... ==> ..., constant */
453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
454 LCONST(d, iptr->sx.val.l);
455 emit_store_dst(jd, iptr, d);
458 case ICMD_FCONST: /* ... ==> ..., constant */
460 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
461 disp = dseg_addfloat(cd, iptr->sx.val.f);
462 M_FLD(d, REG_PV, disp);
463 emit_store_dst(jd, iptr, d);
466 case ICMD_DCONST: /* ... ==> ..., constant */
468 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
469 disp = dseg_adddouble(cd, iptr->sx.val.d);
470 M_DLD(d, REG_PV, disp);
471 emit_store_dst(jd, iptr, d);
474 case ICMD_ACONST: /* ... ==> ..., constant */
476 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
478 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
479 disp = dseg_addaddress(cd, NULL);
481 codegen_addpatchref(cd, PATCHER_aconst,
485 if (opt_showdisassemble) {
489 M_ALD(d, REG_PV, disp);
492 if (iptr->sx.val.anyptr == NULL) {
493 M_INTMOVE(REG_ZERO, d);
495 disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
496 M_ALD(d, REG_PV, disp);
499 emit_store_dst(jd, iptr, d);
503 /* load/store operations **********************************************/
505 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
506 /* s1.localindex = local variable */
508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
509 if ((iptr->dst.var->varkind == LOCALVAR) &&
510 (iptr->dst.var->varnum == iptr->s1.localindex))
512 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
513 if (var->flags & INMEMORY)
514 #if SIZEOF_VOID_P == 8
515 M_LLD(d, REG_SP, var->regoff * 8);
517 M_ILD(d, REG_SP, var->regoff * 8);
520 M_INTMOVE(var->regoff,d);
521 emit_store_dst(jd, iptr, d);
524 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
525 /* s1.localindex = local variable */
527 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
528 if ((iptr->dst.var->varkind == LOCALVAR) &&
529 (iptr->dst.var->varnum == iptr->s1.localindex))
531 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
532 if (var->flags & INMEMORY)
533 M_LLD(d, REG_SP, var->regoff * 8);
535 M_INTMOVE(var->regoff,d);
536 emit_store_dst(jd, iptr, d);
539 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
540 /* s1.localindex = local variable */
542 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
543 if ((iptr->dst.var->varkind == LOCALVAR) &&
544 (iptr->dst.var->varnum == iptr->s1.localindex))
546 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
547 if (var->flags & INMEMORY)
548 M_ALD(d, REG_SP, var->regoff * 8);
550 M_INTMOVE(var->regoff,d);
551 emit_store_dst(jd, iptr, d);
554 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
555 /* s1.localindex = local variable */
557 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
558 if ((iptr->dst.var->varkind == LOCALVAR) &&
559 (iptr->dst.var->varnum == iptr->s1.localindex))
561 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
562 if (var->flags & INMEMORY)
563 M_FLD(d, REG_SP, var->regoff * 8);
565 M_FMOV(var->regoff, d);
566 emit_store_dst(jd, iptr, d);
569 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
570 /* s1.localindex = local variable */
572 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
573 if ((iptr->dst.var->varkind == LOCALVAR) &&
574 (iptr->dst.var->varnum == iptr->s1.localindex))
576 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
577 if (var->flags & INMEMORY)
578 M_DLD(d, REG_SP, var->regoff * 8);
580 M_DMOV(var->regoff, d);
581 emit_store_dst(jd, iptr, d);
585 case ICMD_ISTORE: /* ..., value ==> ... */
586 /* dst.localindex = local variable */
588 if ((iptr->s1.var->varkind == LOCALVAR) &&
589 (iptr->s1.var->varnum == iptr->dst.localindex))
591 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
592 if (var->flags & INMEMORY) {
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 #if SIZEOF_VOID_P == 8
595 M_LST(s1, REG_SP, var->regoff * 8);
597 M_IST(s1, REG_SP, var->regoff * 8);
600 s1 = emit_load_s1(jd, iptr, var->regoff);
601 M_INTMOVE(s1, var->regoff);
605 case ICMD_LSTORE: /* ..., value ==> ... */
606 /* dst.localindex = local variable */
608 if ((iptr->s1.var->varkind == LOCALVAR) &&
609 (iptr->s1.var->varnum == iptr->dst.localindex))
611 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
612 if (var->flags & INMEMORY) {
613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
614 M_LST(s1, REG_SP, var->regoff * 8);
616 s1 = emit_load_s1(jd, iptr, var->regoff);
617 M_INTMOVE(s1, var->regoff);
621 case ICMD_ASTORE: /* ..., value ==> ... */
622 /* dst.localindex = local variable */
624 if ((iptr->s1.var->varkind == LOCALVAR) &&
625 (iptr->s1.var->varnum == iptr->dst.localindex))
627 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
628 if (var->flags & INMEMORY) {
629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
630 M_AST(s1, REG_SP, var->regoff * 8);
632 s1 = emit_load_s1(jd, iptr, var->regoff);
633 M_INTMOVE(s1, var->regoff);
637 case ICMD_FSTORE: /* ..., value ==> ... */
638 /* dst.localindex = local variable */
640 if ((iptr->s1.var->varkind == LOCALVAR) &&
641 (iptr->s1.var->varnum == iptr->dst.localindex))
643 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
644 if (var->flags & INMEMORY) {
645 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
646 M_FST(s1, REG_SP, var->regoff * 8);
648 s1 = emit_load_s1(jd, iptr, var->regoff);
649 M_FMOV(s1, var->regoff);
653 case ICMD_DSTORE: /* ..., value ==> ... */
654 /* dst.localindex = local variable */
656 if ((iptr->s1.var->varkind == LOCALVAR) &&
657 (iptr->s1.var->varnum == iptr->dst.localindex))
659 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
660 if (var->flags & INMEMORY) {
661 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
662 M_DST(s1, REG_SP, var->regoff * 8);
664 s1 = emit_load_s1(jd, iptr, var->regoff);
665 M_DMOV(s1, var->regoff);
670 /* pop/dup/swap operations ********************************************/
672 /* attention: double and longs are only one entry in CACAO ICMDs */
674 case ICMD_POP: /* ..., value ==> ... */
675 case ICMD_POP2: /* ..., value, value ==> ... */
678 case ICMD_DUP: /* ..., a ==> ..., a, a */
680 M_COPY(iptr->s1.var, iptr->dst.var);
683 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
685 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+2]);
686 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
687 M_COPY(iptr->dst.dupslots[2+2], iptr->dst.dupslots[2+0]);
690 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
692 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+3]);
693 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+2]);
694 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+1]);
695 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
698 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
700 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+1]);
701 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+0]);
704 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
706 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[3+4]);
707 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[3+3]);
708 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[3+2]);
709 M_COPY(iptr->dst.dupslots[3+4], iptr->dst.dupslots[3+1]);
710 M_COPY(iptr->dst.dupslots[3+3], iptr->dst.dupslots[3+0]);
713 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
715 M_COPY(iptr->dst.dupslots[ 3], iptr->dst.dupslots[4+5]);
716 M_COPY(iptr->dst.dupslots[ 2], iptr->dst.dupslots[4+4]);
717 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[4+3]);
718 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[4+2]);
719 M_COPY(iptr->dst.dupslots[4+5], iptr->dst.dupslots[4+1]);
720 M_COPY(iptr->dst.dupslots[4+4], iptr->dst.dupslots[4+0]);
723 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
725 M_COPY(iptr->dst.dupslots[ 1], iptr->dst.dupslots[2+0]);
726 M_COPY(iptr->dst.dupslots[ 0], iptr->dst.dupslots[2+1]);
730 /* integer operations *************************************************/
732 case ICMD_INEG: /* ..., value ==> ..., - value */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
736 M_ISUB(REG_ZERO, s1, d);
737 emit_store_dst(jd, iptr, d);
740 case ICMD_LNEG: /* ..., value ==> ..., - value */
742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
744 M_LSUB(REG_ZERO, s1, d);
745 emit_store_dst(jd, iptr, d);
748 case ICMD_I2L: /* ..., value ==> ..., value */
750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
751 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
753 emit_store_dst(jd, iptr, d);
756 case ICMD_L2I: /* ..., value ==> ..., value */
758 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
760 M_ISLL_IMM(s1, 0, d );
761 emit_store_dst(jd, iptr, d);
764 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
768 M_LSLL_IMM(s1, 56, d);
769 M_LSRA_IMM( d, 56, d);
770 emit_store_dst(jd, iptr, d);
773 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
775 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
776 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
778 emit_store_dst(jd, iptr, d);
781 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785 M_LSLL_IMM(s1, 48, d);
786 M_LSRA_IMM( d, 48, d);
787 emit_store_dst(jd, iptr, d);
791 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
795 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
797 emit_store_dst(jd, iptr, d);
800 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
801 /* sx.val.i = constant */
803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
806 M_IADD_IMM(s1, iptr->sx.val.i, d);
808 ICONST(REG_ITMP2, iptr->sx.val.i);
809 M_IADD(s1, REG_ITMP2, d);
811 emit_store_dst(jd, iptr, d);
814 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
818 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
820 emit_store_dst(jd, iptr, d);
823 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
824 /* sx.val.l = constant */
826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
827 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
828 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
829 M_LADD_IMM(s1, iptr->sx.val.l, d);
831 LCONST(REG_ITMP2, iptr->sx.val.l);
832 M_LADD(s1, REG_ITMP2, d);
834 emit_store_dst(jd, iptr, d);
837 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
840 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
841 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 emit_store_dst(jd, iptr, d);
846 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
847 /* sx.val.i = constant */
849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
850 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
851 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768)) {
852 M_IADD_IMM(s1, -iptr->sx.val.i, d);
854 ICONST(REG_ITMP2, iptr->sx.val.i);
855 M_ISUB(s1, REG_ITMP2, d);
857 emit_store_dst(jd, iptr, d);
860 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
863 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
864 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
866 emit_store_dst(jd, iptr, d);
869 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
870 /* sx.val.l = constant */
872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
874 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768)) {
875 M_LADD_IMM(s1, -iptr->sx.val.l, d);
877 LCONST(REG_ITMP2, iptr->sx.val.l);
878 M_LSUB(s1, REG_ITMP2, d);
880 emit_store_dst(jd, iptr, d);
883 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
886 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
887 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
892 emit_store_dst(jd, iptr, d);
895 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
896 /* sx.val.i = constant */
898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
899 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
900 ICONST(REG_ITMP2, iptr->sx.val.i);
901 M_IMUL(s1, REG_ITMP2);
905 emit_store_dst(jd, iptr, d);
908 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
917 emit_store_dst(jd, iptr, d);
920 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
921 /* sx.val.l = constant */
923 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
924 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
925 LCONST(REG_ITMP2, iptr->sx.val.l);
926 M_LMUL(s1, REG_ITMP2);
930 emit_store_dst(jd, iptr, d);
933 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
935 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
936 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
937 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
956 emit_store_dst(jd, iptr, d);
959 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
962 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
963 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
969 emit_store_dst(jd, iptr, d);
972 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
974 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
975 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
976 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
982 emit_store_dst(jd, iptr, d);
985 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
986 case ICMD_LDIVPOW2: /* val.i = constant */
988 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
989 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
990 M_LSRA_IMM(s1, 63, REG_ITMP2);
991 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
992 M_LADD(s1, REG_ITMP2, REG_ITMP2);
993 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
994 emit_store_dst(jd, iptr, d);
997 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1000 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1001 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1003 emit_store_dst(jd, iptr, d);
1006 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1007 /* sx.val.i = constant */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1011 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1012 emit_store_dst(jd, iptr, d);
1015 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1017 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1018 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1019 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1021 emit_store_dst(jd, iptr, d);
1024 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1025 /* sx.val.i = constant */
1027 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1028 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1029 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1030 emit_store_dst(jd, iptr, d);
1033 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1035 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1036 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1039 emit_store_dst(jd, iptr, d);
1042 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1043 /* sx.val.i = constant */
1045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1046 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1047 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1048 emit_store_dst(jd, iptr, d);
1051 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1053 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1054 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1057 emit_store_dst(jd, iptr, d);
1060 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1061 /* sx.val.i = constant */
1063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1066 emit_store_dst(jd, iptr, d);
1069 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1071 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1072 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1073 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1075 emit_store_dst(jd, iptr, d);
1078 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1079 /* sx.val.i = constant */
1081 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1082 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1083 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1090 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1091 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1093 emit_store_dst(jd, iptr, d);
1096 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1097 /* sx.val.i = constant */
1099 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1100 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1101 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1102 emit_store_dst(jd, iptr, d);
1105 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1108 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1109 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1110 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1112 emit_store_dst(jd, iptr, d);
1115 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1116 /* sx.val.i = constant */
1118 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1119 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1120 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1121 M_AND_IMM(s1, iptr->sx.val.i, d);
1123 ICONST(REG_ITMP2, iptr->sx.val.i);
1124 M_AND(s1, REG_ITMP2, d);
1126 emit_store_dst(jd, iptr, d);
1129 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1130 /* sx.val.i = constant */
1132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1135 M_MOV(s1, REG_ITMP1);
1138 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1139 M_AND_IMM(s1, iptr->sx.val.i, d);
1142 M_ISUB(REG_ZERO, s1, d);
1143 M_AND_IMM(d, iptr->sx.val.i, d);
1145 ICONST(REG_ITMP2, iptr->sx.val.i);
1146 M_AND(s1, REG_ITMP2, d);
1149 M_ISUB(REG_ZERO, s1, d);
1150 M_AND(d, REG_ITMP2, d);
1152 M_ISUB(REG_ZERO, d, d);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1157 /* sx.val.l = constant */
1159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1160 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1161 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1162 M_AND_IMM(s1, iptr->sx.val.l, d);
1164 LCONST(REG_ITMP2, iptr->sx.val.l);
1165 M_AND(s1, REG_ITMP2, d);
1167 emit_store_dst(jd, iptr, d);
1170 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1171 /* sx.val.l = constant */
1173 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1174 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1176 M_MOV(s1, REG_ITMP1);
1179 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1180 M_AND_IMM(s1, iptr->sx.val.l, d);
1183 M_LSUB(REG_ZERO, s1, d);
1184 M_AND_IMM(d, iptr->sx.val.l, d);
1186 LCONST(REG_ITMP2, iptr->sx.val.l);
1187 M_AND(s1, REG_ITMP2, d);
1190 M_LSUB(REG_ZERO, s1, d);
1191 M_AND(d, REG_ITMP2, d);
1193 M_LSUB(REG_ZERO, d, d);
1194 emit_store_dst(jd, iptr, d);
1197 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1200 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1201 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1202 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1204 emit_store_dst(jd, iptr, d);
1207 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1208 /* sx.val.i = constant */
1210 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1211 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1212 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1213 M_OR_IMM(s1, iptr->sx.val.i, d);
1215 ICONST(REG_ITMP2, iptr->sx.val.i);
1216 M_OR(s1, REG_ITMP2, d);
1218 emit_store_dst(jd, iptr, d);
1221 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1222 /* sx.val.l = constant */
1224 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1225 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1226 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1227 M_OR_IMM(s1, iptr->sx.val.l, d);
1229 LCONST(REG_ITMP2, iptr->sx.val.l);
1230 M_OR(s1, REG_ITMP2, d);
1232 emit_store_dst(jd, iptr, d);
1235 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1238 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1239 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1240 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1246 /* sx.val.i = constant */
1248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1250 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1251 M_XOR_IMM(s1, iptr->sx.val.i, d);
1253 ICONST(REG_ITMP2, iptr->sx.val.i);
1254 M_XOR(s1, REG_ITMP2, d);
1256 emit_store_dst(jd, iptr, d);
1259 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1260 /* sx.val.l = constant */
1262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1264 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1265 M_XOR_IMM(s1, iptr->sx.val.l, d);
1267 LCONST(REG_ITMP2, iptr->sx.val.l);
1268 M_XOR(s1, REG_ITMP2, d);
1270 emit_store_dst(jd, iptr, d);
1274 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1276 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1277 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1279 M_CMPLT(s1, s2, REG_ITMP3);
1280 M_CMPLT(s2, s1, REG_ITMP1);
1281 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1282 emit_store_dst(jd, iptr, d);
1286 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1287 /* s1.localindex = variable, sx.val.i = constant */
1289 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1290 if (var->flags & INMEMORY) {
1292 M_LLD(s1, REG_SP, var->regoff * 8);
1295 M_IADD_IMM(s1, iptr->sx.val.i, s1);
1296 if (var->flags & INMEMORY)
1297 M_LST(s1, REG_SP, var->regoff * 8);
1301 /* floating operations ************************************************/
1303 case ICMD_FNEG: /* ..., value ==> ..., - value */
1305 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1306 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1308 emit_store_dst(jd, iptr, d);
1311 case ICMD_DNEG: /* ..., value ==> ..., - value */
1313 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1314 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1316 emit_store_dst(jd, iptr, d);
1319 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1321 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1322 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1323 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1325 emit_store_dst(jd, iptr, d);
1328 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1330 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1331 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1332 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1339 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1340 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1341 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1343 emit_store_dst(jd, iptr, d);
1346 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1348 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1349 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1350 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1352 emit_store_dst(jd, iptr, d);
1355 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1357 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1358 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1359 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1361 emit_store_dst(jd, iptr, d);
1364 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1366 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1367 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1368 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1370 emit_store_dst(jd, iptr, d);
1373 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1375 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1376 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1377 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1379 emit_store_dst(jd, iptr, d);
1382 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1384 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1385 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1386 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1388 emit_store_dst(jd, iptr, d);
1392 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1394 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1395 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1396 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1397 M_FDIV(s1,s2, REG_FTMP3);
1398 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1399 M_CVTLF(REG_FTMP3, REG_FTMP3);
1400 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1401 M_FSUB(s1, REG_FTMP3, d);
1402 emit_store_dst(jd, iptr, d);
1405 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % 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_FTMP3);
1410 M_DDIV(s1,s2, REG_FTMP3);
1411 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1412 M_CVTLD(REG_FTMP3, REG_FTMP3);
1413 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1414 M_DSUB(s1, REG_FTMP3, d);
1415 emit_store_dst(jd, iptr, d);
1419 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1421 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1422 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1434 emit_store_dst(jd, iptr, d);
1438 /* XXX these do not work correctly */
1440 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1442 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1443 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1444 M_TRUNCFI(s1, REG_FTMP1);
1445 M_MOVDI(REG_FTMP1, d);
1447 emit_store_dst(jd, iptr, d);
1450 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1452 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1453 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1454 M_TRUNCDI(s1, REG_FTMP1);
1455 M_MOVDI(REG_FTMP1, d);
1457 emit_store_dst(jd, iptr, d);
1460 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1462 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1464 M_TRUNCFL(s1, REG_FTMP1);
1465 M_MOVDL(REG_FTMP1, d);
1467 emit_store_dst(jd, iptr, d);
1470 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1472 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1473 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1474 M_TRUNCDL(s1, REG_FTMP1);
1475 M_MOVDL(REG_FTMP1, d);
1477 emit_store_dst(jd, iptr, d);
1481 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1483 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1484 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1486 emit_store_dst(jd, iptr, d);
1489 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1491 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1492 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1494 emit_store_dst(jd, iptr, d);
1497 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1499 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1500 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1504 M_LADD_IMM(REG_ZERO, 1, d);
1508 M_LSUB_IMM(REG_ZERO, 1, d);
1509 M_CMOVT(REG_ZERO, d);
1510 emit_store_dst(jd, iptr, d);
1513 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1515 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1520 M_LADD_IMM(REG_ZERO, 1, d);
1524 M_LSUB_IMM(REG_ZERO, 1, d);
1525 M_CMOVT(REG_ZERO, d);
1526 emit_store_dst(jd, iptr, d);
1529 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1531 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1532 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1533 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1536 M_LSUB_IMM(REG_ZERO, 1, d);
1540 M_LADD_IMM(REG_ZERO, 1, d);
1541 M_CMOVT(REG_ZERO, d);
1542 emit_store_dst(jd, iptr, d);
1545 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1547 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1548 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1549 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1552 M_LSUB_IMM(REG_ZERO, 1, d);
1556 M_LADD_IMM(REG_ZERO, 1, d);
1557 M_CMOVT(REG_ZERO, d);
1558 emit_store_dst(jd, iptr, d);
1562 /* memory operations **************************************************/
1564 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1566 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1567 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1568 gen_nullptr_check(s1);
1569 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1570 emit_store_dst(jd, iptr, d);
1573 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1575 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1576 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1578 if (INSTRUCTION_MUST_CHECK(iptr)) {
1579 gen_nullptr_check(s1);
1582 M_AADD(s2, s1, REG_ITMP3);
1583 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1584 emit_store_dst(jd, iptr, d);
1587 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1590 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1592 if (INSTRUCTION_MUST_CHECK(iptr)) {
1593 gen_nullptr_check(s1);
1596 M_AADD(s2, s1, REG_ITMP3);
1597 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1598 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1599 emit_store_dst(jd, iptr, d);
1602 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1604 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1605 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1607 if (INSTRUCTION_MUST_CHECK(iptr)) {
1608 gen_nullptr_check(s1);
1611 M_AADD(s2, s1, REG_ITMP3);
1612 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1613 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1614 emit_store_dst(jd, iptr, d);
1617 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1621 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1622 if (INSTRUCTION_MUST_CHECK(iptr)) {
1623 gen_nullptr_check(s1);
1626 M_ASLL_IMM(s2, 2, REG_ITMP3);
1627 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1628 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1629 emit_store_dst(jd, iptr, d);
1632 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1635 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1637 if (INSTRUCTION_MUST_CHECK(iptr)) {
1638 gen_nullptr_check(s1);
1641 M_ASLL_IMM(s2, 3, REG_ITMP3);
1642 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1643 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1644 emit_store_dst(jd, iptr, d);
1647 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1651 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1652 if (INSTRUCTION_MUST_CHECK(iptr)) {
1653 gen_nullptr_check(s1);
1656 M_ASLL_IMM(s2, 2, REG_ITMP3);
1657 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1658 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1659 emit_store_dst(jd, iptr, d);
1662 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1666 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1667 if (INSTRUCTION_MUST_CHECK(iptr)) {
1668 gen_nullptr_check(s1);
1671 M_ASLL_IMM(s2, 3, REG_ITMP3);
1672 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1673 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1674 emit_store_dst(jd, iptr, d);
1677 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1680 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1681 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1682 if (INSTRUCTION_MUST_CHECK(iptr)) {
1683 gen_nullptr_check(s1);
1686 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1687 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1688 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1689 emit_store_dst(jd, iptr, d);
1693 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1697 if (INSTRUCTION_MUST_CHECK(iptr)) {
1698 gen_nullptr_check(s1);
1701 M_AADD(s2, s1, REG_ITMP1);
1702 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1703 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1706 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1707 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1711 if (INSTRUCTION_MUST_CHECK(iptr)) {
1712 gen_nullptr_check(s1);
1715 M_AADD(s2, s1, REG_ITMP1);
1716 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1717 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1718 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1721 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1723 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1724 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1725 if (INSTRUCTION_MUST_CHECK(iptr)) {
1726 gen_nullptr_check(s1);
1729 M_ASLL_IMM(s2, 2, REG_ITMP2);
1730 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1731 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1732 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1735 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1738 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1739 if (INSTRUCTION_MUST_CHECK(iptr)) {
1740 gen_nullptr_check(s1);
1743 M_ASLL_IMM(s2, 3, REG_ITMP2);
1744 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1745 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1746 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1749 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1753 if (INSTRUCTION_MUST_CHECK(iptr)) {
1754 gen_nullptr_check(s1);
1757 M_ASLL_IMM(s2, 2, REG_ITMP2);
1758 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1759 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1760 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1763 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1767 if (INSTRUCTION_MUST_CHECK(iptr)) {
1768 gen_nullptr_check(s1);
1771 M_ASLL_IMM(s2, 3, REG_ITMP2);
1772 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1773 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1774 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1778 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1781 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1782 if (INSTRUCTION_MUST_CHECK(iptr)) {
1783 gen_nullptr_check(s1);
1786 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1790 disp = dseg_addaddress(cd, BUILTIN_canstore);
1791 M_ALD(REG_ITMP3, REG_PV, disp);
1792 M_JSR(REG_RA, REG_ITMP3);
1795 M_BEQZ(REG_RESULT, 0);
1796 codegen_add_arraystoreexception_ref(cd);
1799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1800 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1801 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1802 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1803 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1804 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1808 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1811 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1812 if (INSTRUCTION_MUST_CHECK(iptr)) {
1813 gen_nullptr_check(s1);
1816 M_AADD(s2, s1, REG_ITMP1);
1817 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1820 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1821 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1824 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1825 if (INSTRUCTION_MUST_CHECK(iptr)) {
1826 gen_nullptr_check(s1);
1829 M_AADD(s2, s1, REG_ITMP1);
1830 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1831 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1834 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1836 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1837 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1838 if (INSTRUCTION_MUST_CHECK(iptr)) {
1839 gen_nullptr_check(s1);
1842 M_ASLL_IMM(s2, 2, REG_ITMP2);
1843 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1844 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1847 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1849 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1850 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1851 if (INSTRUCTION_MUST_CHECK(iptr)) {
1852 gen_nullptr_check(s1);
1855 M_ASLL_IMM(s2, 3, REG_ITMP2);
1856 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1857 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1860 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1863 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1864 if (INSTRUCTION_MUST_CHECK(iptr)) {
1865 gen_nullptr_check(s1);
1868 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1869 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1870 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1874 case ICMD_GETSTATIC: /* ... ==> ..., value */
1876 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1877 unresolved_field *uf = iptr->sx.s23.s3.uf;
1879 fieldtype = uf->fieldref->parseddesc.fd->type;
1880 disp = dseg_addaddress(cd, NULL);
1882 codegen_addpatchref(cd, PATCHER_get_putstatic,
1883 iptr->sx.s23.s3.uf, disp);
1885 if (opt_showdisassemble) {
1890 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1892 fieldtype = fi->type;
1893 disp = dseg_addaddress(cd, &(fi->value));
1895 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1896 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1898 if (opt_showdisassemble) {
1904 M_ALD(REG_ITMP1, REG_PV, disp);
1905 switch (fieldtype) {
1907 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1908 M_ILD_INTERN(d, REG_ITMP1, 0);
1909 emit_store_dst(jd, iptr, d);
1912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1913 M_LLD_INTERN(d, REG_ITMP1, 0);
1914 emit_store_dst(jd, iptr, d);
1917 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1918 M_ALD_INTERN(d, REG_ITMP1, 0);
1919 emit_store_dst(jd, iptr, d);
1922 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1923 M_FLD_INTERN(d, REG_ITMP1, 0);
1924 emit_store_dst(jd, iptr, d);
1927 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1928 M_DLD_INTERN(d, REG_ITMP1, 0);
1929 emit_store_dst(jd, iptr, d);
1934 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1936 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1937 unresolved_field *uf = iptr->sx.s23.s3.uf;
1939 fieldtype = uf->fieldref->parseddesc.fd->type;
1940 disp = dseg_addaddress(cd, NULL);
1942 codegen_addpatchref(cd, PATCHER_get_putstatic,
1943 iptr->sx.s23.s3.uf, disp);
1945 if (opt_showdisassemble) {
1950 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1952 fieldtype = fi->type;
1953 disp = dseg_addaddress(cd, &(fi->value));
1955 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1956 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1958 if (opt_showdisassemble) {
1964 M_ALD(REG_ITMP1, REG_PV, disp);
1965 switch (fieldtype) {
1967 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1968 M_IST_INTERN(s1, REG_ITMP1, 0);
1971 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1972 M_LST_INTERN(s1, REG_ITMP1, 0);
1975 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1976 M_AST_INTERN(s1, REG_ITMP1, 0);
1979 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1980 M_FST_INTERN(s1, REG_ITMP1, 0);
1983 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1984 M_DST_INTERN(s1, REG_ITMP1, 0);
1989 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1990 /* val = value (in current instruction) */
1991 /* following NOP) */
1993 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1994 unresolved_field *uf = iptr->sx.s23.s3.uf;
1996 fieldtype = uf->fieldref->parseddesc.fd->type;
1997 disp = dseg_addaddress(cd, NULL);
1999 codegen_addpatchref(cd, PATCHER_get_putstatic,
2002 if (opt_showdisassemble) {
2007 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2009 fieldtype = fi->type;
2010 disp = dseg_addaddress(cd, &(fi->value));
2012 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2013 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2015 if (opt_showdisassemble) {
2021 M_ALD(REG_ITMP1, REG_PV, disp);
2022 switch (fieldtype) {
2024 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2027 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2030 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2033 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2036 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2042 case ICMD_GETFIELD: /* ... ==> ..., value */
2044 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2045 gen_nullptr_check(s1);
2047 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2048 unresolved_field *uf = iptr->sx.s23.s3.uf;
2050 fieldtype = uf->fieldref->parseddesc.fd->type;
2052 codegen_addpatchref(cd, PATCHER_get_putfield,
2053 iptr->sx.s23.s3.uf, 0);
2055 if (opt_showdisassemble) {
2062 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2063 fieldtype = fi->type;
2067 switch (fieldtype) {
2069 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2071 emit_store_dst(jd, iptr, d);
2074 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2076 emit_store_dst(jd, iptr, d);
2079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2081 emit_store_dst(jd, iptr, d);
2084 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2086 emit_store_dst(jd, iptr, d);
2089 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2091 emit_store_dst(jd, iptr, d);
2096 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2098 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2099 gen_nullptr_check(s1);
2101 if (!IS_FLT_DBL_TYPE(fieldtype)) {
2102 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2104 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2107 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2108 unresolved_field *uf = iptr->sx.s23.s3.uf;
2110 fieldtype = uf->fieldref->parseddesc.fd->type;
2112 codegen_addpatchref(cd, PATCHER_get_putfield,
2113 iptr->sx.s23.s3.uf, 0);
2115 if (opt_showdisassemble) {
2122 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2123 fieldtype = fi->type;
2127 switch (fieldtype) {
2146 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2147 /* val = value (in current instruction) */
2148 /* following NOP) */
2150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151 gen_nullptr_check(s1);
2153 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2154 unresolved_field *uf = iptr->sx.s23.s3.uf;
2156 fieldtype = uf->fieldref->parseddesc.fd->type;
2158 codegen_addpatchref(cd, PATCHER_get_putfield,
2161 if (opt_showdisassemble) {
2168 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2169 fieldtype = fi->type;
2173 switch (fieldtype) {
2175 M_IST(REG_ZERO, s1, a);
2178 M_LST(REG_ZERO, s1, a);
2181 M_AST(REG_ZERO, s1, a);
2184 M_FST(REG_ZERO, s1, a);
2187 M_DST(REG_ZERO, s1, a);
2193 /* branch operations **************************************************/
2195 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2197 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2198 M_INTMOVE(s1, REG_ITMP1_XPTR);
2200 #ifdef ENABLE_VERIFIER
2201 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2202 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2203 iptr->sx.s23.s2.uc, 0);
2205 if (opt_showdisassemble) {
2209 #endif /* ENABLE_VERIFIER */
2211 disp = dseg_addaddress(cd, asm_handle_exception);
2212 M_ALD(REG_ITMP2, REG_PV, disp);
2213 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2215 M_NOP; /* nop ensures that XPC is less than the end */
2216 /* of basic block */
2220 case ICMD_GOTO: /* ... ==> ... */
2222 codegen_addreference(cd, iptr->dst.block);
2227 case ICMD_JSR: /* ... ==> ... */
2229 dseg_addtarget(cd, iptr->sx.s23.s3.jsrtarget.block);
2230 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2231 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2235 case ICMD_RET: /* ... ==> ... */
2236 /* s1.localindex = local variable */
2237 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
2238 if (var->flags & INMEMORY) {
2239 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2247 case ICMD_IFNULL: /* ..., value ==> ... */
2249 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2251 codegen_addreference(cd, iptr->dst.block);
2255 case ICMD_IFNONNULL: /* ..., value ==> ... */
2257 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2259 codegen_addreference(cd, iptr->dst.block);
2263 case ICMD_IFEQ: /* ..., value ==> ... */
2265 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2266 if (iptr->sx.val.i == 0) {
2269 ICONST(REG_ITMP2, iptr->sx.val.i);
2270 M_BEQ(s1, REG_ITMP2, 0);
2272 codegen_addreference(cd, iptr->dst.block);
2276 case ICMD_IFLT: /* ..., value ==> ... */
2278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2279 if (iptr->sx.val.i == 0) {
2282 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2283 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2285 ICONST(REG_ITMP2, iptr->sx.val.i);
2286 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2288 M_BNEZ(REG_ITMP1, 0);
2290 codegen_addreference(cd, iptr->dst.block);
2294 case ICMD_IFLE: /* ..., value ==> ... */
2296 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2297 if (iptr->sx.val.i == 0) {
2301 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2302 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2303 M_BNEZ(REG_ITMP1, 0);
2306 ICONST(REG_ITMP2, iptr->sx.val.i);
2307 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2308 M_BEQZ(REG_ITMP1, 0);
2311 codegen_addreference(cd, iptr->dst.block);
2315 case ICMD_IFNE: /* ..., value ==> ... */
2317 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2318 if (iptr->sx.val.i == 0) {
2322 ICONST(REG_ITMP2, iptr->sx.val.i);
2323 M_BNE(s1, REG_ITMP2, 0);
2325 codegen_addreference(cd, iptr->dst.block);
2329 case ICMD_IFGT: /* ..., value ==> ... */
2331 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2332 if (iptr->sx.val.i == 0) {
2336 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2337 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2338 M_BEQZ(REG_ITMP1, 0);
2341 ICONST(REG_ITMP2, iptr->sx.val.i);
2342 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2343 M_BNEZ(REG_ITMP1, 0);
2346 codegen_addreference(cd, iptr->dst.block);
2350 case ICMD_IFGE: /* ..., value ==> ... */
2352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2353 if (iptr->sx.val.i == 0) {
2357 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2358 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2361 ICONST(REG_ITMP2, iptr->sx.val.i);
2362 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2364 M_BEQZ(REG_ITMP1, 0);
2366 codegen_addreference(cd, iptr->dst.block);
2370 case ICMD_IF_LEQ: /* ..., value ==> ... */
2372 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2373 if (iptr->sx.val.l == 0) {
2377 LCONST(REG_ITMP2, iptr->sx.val.l);
2378 M_BEQ(s1, REG_ITMP2, 0);
2380 codegen_addreference(cd, iptr->dst.block);
2384 case ICMD_IF_LLT: /* ..., value ==> ... */
2386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2387 if (iptr->sx.val.l == 0) {
2391 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2392 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2395 LCONST(REG_ITMP2, iptr->sx.val.l);
2396 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2398 M_BNEZ(REG_ITMP1, 0);
2400 codegen_addreference(cd, iptr->dst.block);
2404 case ICMD_IF_LLE: /* ..., value ==> ... */
2406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2407 if (iptr->sx.val.l == 0) {
2411 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2412 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2413 M_BNEZ(REG_ITMP1, 0);
2416 LCONST(REG_ITMP2, iptr->sx.val.l);
2417 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2418 M_BEQZ(REG_ITMP1, 0);
2421 codegen_addreference(cd, iptr->dst.block);
2425 case ICMD_IF_LNE: /* ..., value ==> ... */
2427 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2428 if (iptr->sx.val.l == 0) {
2432 LCONST(REG_ITMP2, iptr->sx.val.l);
2433 M_BNE(s1, REG_ITMP2, 0);
2435 codegen_addreference(cd, iptr->dst.block);
2439 case ICMD_IF_LGT: /* ..., value ==> ... */
2441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2442 if (iptr->sx.val.l == 0) {
2446 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2447 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2448 M_BEQZ(REG_ITMP1, 0);
2451 LCONST(REG_ITMP2, iptr->sx.val.l);
2452 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2453 M_BNEZ(REG_ITMP1, 0);
2456 codegen_addreference(cd, iptr->dst.block);
2460 case ICMD_IF_LGE: /* ..., value ==> ... */
2462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2463 if (iptr->sx.val.l == 0) {
2467 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2468 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2471 LCONST(REG_ITMP2, iptr->sx.val.l);
2472 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2474 M_BEQZ(REG_ITMP1, 0);
2476 codegen_addreference(cd, iptr->dst.block);
2480 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2481 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2482 case ICMD_IF_ACMPEQ:
2484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2485 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2487 codegen_addreference(cd, iptr->dst.block);
2491 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2492 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2493 case ICMD_IF_ACMPNE:
2495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2496 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2498 codegen_addreference(cd, iptr->dst.block);
2502 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2503 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2505 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2506 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2507 M_CMPLT(s1, s2, REG_ITMP1);
2508 M_BNEZ(REG_ITMP1, 0);
2509 codegen_addreference(cd, iptr->dst.block);
2513 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2514 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2517 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2518 M_CMPGT(s1, s2, REG_ITMP1);
2519 M_BNEZ(REG_ITMP1, 0);
2520 codegen_addreference(cd, iptr->dst.block);
2524 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2525 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2527 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2528 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2529 M_CMPGT(s1, s2, REG_ITMP1);
2530 M_BEQZ(REG_ITMP1, 0);
2531 codegen_addreference(cd, iptr->dst.block);
2535 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2536 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2539 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2540 M_CMPLT(s1, s2, REG_ITMP1);
2541 M_BEQZ(REG_ITMP1, 0);
2542 codegen_addreference(cd, iptr->dst.block);
2547 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2550 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2551 M_INTMOVE(s1, REG_RESULT);
2552 goto nowperformreturn;
2554 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2556 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2557 M_INTMOVE(s1, REG_RESULT);
2559 #ifdef ENABLE_VERIFIER
2560 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2561 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2562 iptr->sx.s23.s2.uc, 0);
2564 if (opt_showdisassemble) {
2568 #endif /* ENABLE_VERIFIER */
2569 goto nowperformreturn;
2571 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2573 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2574 M_FLTMOVE(s1, REG_FRESULT);
2575 goto nowperformreturn;
2577 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2579 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2580 M_DBLMOVE(s1, REG_FRESULT);
2581 goto nowperformreturn;
2583 case ICMD_RETURN: /* ... ==> ... */
2589 p = cd->stackframesize;
2591 #if !defined(NDEBUG)
2592 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2593 emit_verbosecall_exit(jd);
2596 #if defined(ENABLE_THREADS)
2597 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2598 disp = dseg_addaddress(cd, LOCK_monitor_exit);
2599 M_ALD(REG_ITMP3, REG_PV, disp);
2601 /* we need to save the proper return value */
2603 switch (iptr->opc) {
2607 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2608 M_JSR(REG_RA, REG_ITMP3);
2609 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2613 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2614 M_JSR(REG_RA, REG_ITMP3);
2615 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2618 M_JSR(REG_RA, REG_ITMP3);
2619 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2623 /* and now restore the proper return value */
2625 switch (iptr->opc) {
2629 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2633 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2639 /* restore return address */
2641 if (!jd->isleafmethod) {
2642 p--; M_ALD(REG_RA, REG_SP, p * 8);
2645 /* restore saved registers */
2647 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2648 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2650 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2651 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2654 /* deallocate stack and return */
2656 if (cd->stackframesize) {
2659 disp = cd->stackframesize * 8;
2660 lo = (short) (disp);
2661 hi = (short) (((disp) - lo) >> 16);
2665 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2667 M_LUI(REG_ITMP3,hi);
2668 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2670 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2683 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2686 branch_target_t *table;
2688 table = iptr->dst.table;
2690 l = iptr->sx.s23.s2.tablelow;
2691 i = iptr->sx.s23.s3.tablehigh;
2693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2695 {M_INTMOVE(s1, REG_ITMP1);}
2696 else if (l <= 32768) {
2697 M_IADD_IMM(s1, -l, REG_ITMP1);
2700 ICONST(REG_ITMP2, l);
2701 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2704 /* number of targets */
2709 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2710 M_BEQZ(REG_ITMP2, 0);
2711 codegen_addreference(cd, table[0].block); /* default target */
2712 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2714 /* build jump table top down and use address of lowest entry */
2719 dseg_addtarget(cd, table->block);
2724 /* length of dataseg after last dseg_addtarget is used by load */
2726 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2727 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2734 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2737 lookup_target_t *lookup;
2739 lookup = iptr->dst.lookup;
2741 i = iptr->sx.s23.s2.lookupcount;
2743 MCODECHECK((i<<2)+8);
2744 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2747 ICONST(REG_ITMP2, lookup->value);
2748 M_BEQ(s1, REG_ITMP2, 0);
2749 codegen_addreference(cd, lookup->target.block);
2755 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2762 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2764 bte = iptr->sx.s23.s3.bte;
2768 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2770 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2771 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2772 case ICMD_INVOKEINTERFACE:
2774 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2776 um = iptr->sx.s23.s3.um;
2777 md = um->methodref->parseddesc.md;
2780 lm = iptr->sx.s23.s3.fmiref->p.method;
2782 md = lm->parseddesc;
2786 s3 = md->paramcount;
2788 MCODECHECK((s3 << 1) + 64);
2790 /* copy arguments to registers or stack location */
2792 for (s3 = s3 - 1; s3 >= 0; s3--) {
2793 src = iptr->sx.s23.s2.args[s3];
2795 if (src->varkind == ARGVAR)
2798 if (IS_INT_LNG_TYPE(src->type)) {
2799 if (!md->params[s3].inmemory) {
2800 s1 = rd->argintregs[md->params[s3].regoff];
2801 d = emit_load(jd, iptr, src, s1);
2805 d = emit_load(jd, iptr, src, REG_ITMP1);
2806 M_LST(d, REG_SP, md->params[s3].regoff * 8);
2810 if (!md->params[s3].inmemory) {
2811 s1 = rd->argfltregs[md->params[s3].regoff];
2812 d = emit_load(jd, iptr, src, s1);
2813 if (IS_2_WORD_TYPE(src->type))
2819 d = emit_load(jd, iptr, src, REG_FTMP1);
2820 if (IS_2_WORD_TYPE(src->type))
2821 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2823 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2828 switch (iptr->opc) {
2830 disp = dseg_addaddress(cd, bte->fp);
2832 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2834 /* TWISTI: i actually don't know the reason for using
2835 REG_ITMP3 here instead of REG_PV. */
2839 case ICMD_INVOKESPECIAL:
2841 codegen_add_nullpointerexception_ref(cd);
2845 case ICMD_INVOKESTATIC:
2847 disp = dseg_addaddress(cd, NULL);
2849 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2852 if (opt_showdisassemble) {
2857 disp = dseg_addaddress(cd, lm->stubroutine);
2859 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
2863 case ICMD_INVOKEVIRTUAL:
2864 gen_nullptr_check(REG_A0);
2867 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2869 if (opt_showdisassemble) {
2876 s1 = OFFSET(vftbl_t, table[0]) +
2877 sizeof(methodptr) * lm->vftblindex;
2879 M_ALD(REG_METHODPTR, REG_A0,
2880 OFFSET(java_objectheader, vftbl));
2881 M_ALD(REG_PV, REG_METHODPTR, s1);
2885 case ICMD_INVOKEINTERFACE:
2886 gen_nullptr_check(REG_A0);
2889 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2891 if (opt_showdisassemble) {
2899 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2900 sizeof(methodptr*) * lm->class->index;
2902 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2905 M_ALD(REG_METHODPTR, REG_A0,
2906 OFFSET(java_objectheader, vftbl));
2907 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2908 M_ALD(REG_PV, REG_METHODPTR, s2);
2913 /* generate the actual call */
2917 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2918 M_LDA(REG_PV, REG_RA, -disp);
2920 /* actually only used for ICMD_BUILTIN */
2922 if (INSTRUCTION_MUST_CHECK(iptr)) {
2923 M_BEQZ(REG_RESULT, 0);
2924 codegen_add_fillinstacktrace_ref(cd);
2928 /* store return value */
2930 d = md->returntype.type;
2932 if (d != TYPE_VOID) {
2933 if (IS_INT_LNG_TYPE(d)) {
2934 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
2935 M_INTMOVE(REG_RESULT, s1);
2938 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2939 if (IS_2_WORD_TYPE(d))
2940 M_DMOV(REG_FRESULT, s1);
2942 M_FMOV(REG_FRESULT, s1);
2944 emit_store_dst(jd, iptr, s1);
2949 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2950 /* val.a: (classinfo*) superclass */
2952 /* superclass is an interface:
2954 * OK if ((sub == NULL) ||
2955 * (sub->vftbl->interfacetablelength > super->index) &&
2956 * (sub->vftbl->interfacetable[-super->index] != NULL));
2958 * superclass is a class:
2960 * OK if ((sub == NULL) || (0
2961 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2962 * super->vftbl->diffvall));
2965 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2967 vftbl_t *supervftbl;
2970 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2976 super = iptr->sx.s23.s3.c.cls;
2977 superindex = super->index;
2978 supervftbl = super->vftbl;
2981 #if defined(ENABLE_THREADS)
2982 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2985 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2987 /* calculate interface checkcast code size */
2991 s2 += (opt_showdisassemble ? 2 : 0);
2993 /* calculate class checkcast code size */
2995 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2997 s3 += (opt_showdisassemble ? 2 : 0);
2999 /* if class is not resolved, check which code to call */
3001 if (super == NULL) {
3002 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3005 disp = dseg_adds4(cd, 0); /* super->flags */
3007 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3008 iptr->sx.s23.s3.c.ref,
3011 if (opt_showdisassemble) {
3015 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3016 M_ILD(REG_ITMP2, REG_PV, disp);
3017 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3018 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3022 /* interface checkcast code */
3024 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3025 if (super != NULL) {
3030 codegen_addpatchref(cd,
3031 PATCHER_checkcast_instanceof_interface,
3032 iptr->sx.s23.s3.c.ref,
3035 if (opt_showdisassemble) {
3040 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3041 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3042 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3043 M_BLEZ(REG_ITMP3, 0);
3044 codegen_add_classcastexception_ref(cd, s1);
3046 M_ALD(REG_ITMP3, REG_ITMP2,
3047 OFFSET(vftbl_t, interfacetable[0]) -
3048 superindex * sizeof(methodptr*));
3049 M_BEQZ(REG_ITMP3, 0);
3050 codegen_add_classcastexception_ref(cd, s1);
3053 if (super == NULL) {
3059 /* class checkcast code */
3061 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3062 disp = dseg_addaddress(cd, (void *) supervftbl);
3064 if (super != NULL) {
3069 codegen_addpatchref(cd,
3070 PATCHER_checkcast_instanceof_class,
3071 iptr->sx.s23.s3.c.ref,
3074 if (opt_showdisassemble) {
3079 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3080 M_ALD(REG_ITMP3, REG_PV, disp);
3081 #if defined(ENABLE_THREADS)
3082 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3084 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3085 /* if (s1 != REG_ITMP1) { */
3086 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3087 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3088 /* #if defined(ENABLE_THREADS) */
3089 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3091 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3093 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3094 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3095 M_ALD(REG_ITMP3, REG_PV, disp);
3096 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3097 #if defined(ENABLE_THREADS)
3098 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3101 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3102 M_BNEZ(REG_ITMP3, 0);
3103 codegen_add_classcastexception_ref(cd, s1);
3107 d = codegen_reg_of_dst(jd, iptr, s1);
3110 s1 = emit_load_s1(jd, iptr, REG_A0);
3111 M_INTMOVE(s1, REG_A0);
3113 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3115 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3116 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3117 iptr->sx.s23.s3.c.ref,
3120 if (opt_showdisassemble) {
3125 M_ALD(REG_A1, REG_PV, disp);
3126 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3127 M_ALD(REG_ITMP3, REG_PV, disp);
3128 M_JSR(REG_RA, REG_ITMP3);
3131 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3132 M_BEQZ(REG_RESULT, 0);
3133 codegen_add_classcastexception_ref(cd, s1);
3136 d = codegen_reg_of_dst(jd, iptr, s1);
3140 emit_store_dst(jd, iptr, d);
3143 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3144 /* val.a: (classinfo*) superclass */
3146 /* superclass is an interface:
3148 * return (sub != NULL) &&
3149 * (sub->vftbl->interfacetablelength > super->index) &&
3150 * (sub->vftbl->interfacetable[-super->index] != NULL);
3152 * superclass is a class:
3154 * return ((sub != NULL) && (0
3155 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3156 * super->vftbl->diffvall));
3161 vftbl_t *supervftbl;
3164 super = iptr->sx.s23.s3.c.cls;
3166 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3172 super = iptr->sx.s23.s3.c.cls;
3173 superindex = super->index;
3174 supervftbl = super->vftbl;
3177 #if defined(ENABLE_THREADS)
3178 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3181 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3182 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3184 M_MOV(s1, REG_ITMP1);
3188 /* calculate interface instanceof code size */
3192 s2 += (opt_showdisassemble ? 2 : 0);
3194 /* calculate class instanceof code size */
3198 s3 += (opt_showdisassemble ? 2 : 0);
3202 /* if class is not resolved, check which code to call */
3204 if (super == NULL) {
3205 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3208 disp = dseg_adds4(cd, 0); /* super->flags */
3210 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3211 iptr->sx.s23.s3.c.ref, disp);
3213 if (opt_showdisassemble) {
3217 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3218 M_ILD(REG_ITMP3, REG_PV, disp);
3219 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3220 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3224 /* interface instanceof code */
3226 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3227 if (super != NULL) {
3232 codegen_addpatchref(cd,
3233 PATCHER_checkcast_instanceof_interface,
3234 iptr->sx.s23.s3.c.ref, 0);
3236 if (opt_showdisassemble) {
3241 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3242 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3243 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3244 M_BLEZ(REG_ITMP3, 3);
3246 M_ALD(REG_ITMP1, REG_ITMP1,
3247 OFFSET(vftbl_t, interfacetable[0]) -
3248 superindex * sizeof(methodptr*));
3249 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3251 if (super == NULL) {
3257 /* class instanceof code */
3259 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3260 disp = dseg_addaddress(cd, supervftbl);
3262 if (super != NULL) {
3267 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3268 iptr->sx.s23.s3.c.ref,
3271 if (opt_showdisassemble) {
3276 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3277 M_ALD(REG_ITMP2, REG_PV, disp);
3278 #if defined(ENABLE_THREADS)
3279 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3281 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3282 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3283 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3284 #if defined(ENABLE_THREADS)
3285 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3287 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3288 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3291 emit_store_dst(jd, iptr, d);
3295 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3297 /* check for negative sizes and copy sizes to stack if necessary */
3299 MCODECHECK((iptr->s1.argcount << 1) + 64);
3301 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3303 src = iptr->sx.s23.s2.args[s1];
3305 /* copy SAVEDVAR sizes to stack */
3307 if (src->varkind != ARGVAR) {
3308 s2 = emit_load(jd, iptr, src, REG_ITMP1);
3309 M_LST(s2, REG_SP, s1 * 8);
3313 /* a0 = dimension count */
3315 ICONST(REG_A0, iptr->s1.argcount);
3317 /* is patcher function set? */
3319 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3320 disp = dseg_addaddress(cd, NULL);
3322 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3323 iptr->sx.s23.s3.c.ref, disp);
3325 if (opt_showdisassemble) {
3330 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
3333 /* a1 = arraydescriptor */
3335 M_ALD(REG_A1, REG_PV, disp);
3337 /* a2 = pointer to dimensions = stack pointer */
3339 M_INTMOVE(REG_SP, REG_A2);
3341 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3342 M_ALD(REG_ITMP3, REG_PV, disp);
3343 M_JSR(REG_RA, REG_ITMP3);
3346 /* check for exception before result assignment */
3348 M_BEQZ(REG_RESULT, 0);
3349 codegen_add_fillinstacktrace_ref(cd);
3352 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3353 M_INTMOVE(REG_RESULT, d);
3354 emit_store_dst(jd, iptr, d);
3358 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3362 } /* for instruction */
3364 /* copy values to interface registers */
3366 len = bptr->outdepth;
3368 #if defined(ENABLE_LSRA)
3373 src = bptr->outvars[len];
3374 if ((src->varkind != STACKVAR)) {
3376 if (IS_FLT_DBL_TYPE(s2)) {
3377 s1 = emit_load(jd, iptr, src, REG_FTMP1);
3378 if (rd->interfaces[len][s2].flags & INMEMORY) {
3379 if (IS_2_WORD_TYPE(s2))
3380 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3382 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3385 if (IS_2_WORD_TYPE(s2))
3386 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3388 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3392 s1 = emit_load(jd, iptr, src, REG_ITMP1);
3393 if (rd->interfaces[len][s2].flags & INMEMORY)
3394 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3396 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3401 /* At the end of a basic block we may have to append some nops,
3402 because the patcher stub calling code might be longer than the
3403 actual instruction. So codepatching does not change the
3404 following block unintentionally. */
3406 if (cd->mcodeptr < cd->lastmcodeptr) {
3407 while (cd->mcodeptr < cd->lastmcodeptr)
3411 } /* if (bptr -> flags >= BBREACHED) */
3412 } /* for basic block */
3414 dseg_createlinenumbertable(cd);
3416 /* generate exception and patcher stubs */
3418 emit_exception_stubs(jd);
3419 emit_patcher_stubs(jd);
3422 emit_replacement_stubs(jd);
3427 /* everything's ok */
3433 /* createcompilerstub **********************************************************
3435 Creates a stub routine which calls the compiler.
3437 *******************************************************************************/
3439 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3440 #define COMPILERSTUB_CODESIZE 4 * 4
3442 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3445 u1 *createcompilerstub(methodinfo *m)
3447 u1 *s; /* memory to hold the stub */
3453 s = CNEW(u1, COMPILERSTUB_SIZE);
3455 /* set data pointer and code pointer */
3458 s = s + COMPILERSTUB_DATASIZE;
3460 /* mark start of dump memory area */
3462 dumpsize = dump_size();
3464 cd = DNEW(codegendata);
3467 /* Store the codeinfo pointer in the same place as in the
3468 methodheader for compiled methods. */
3470 code = code_codeinfo_new(m);
3472 d[0] = (ptrint) asm_call_jit_compiler;
3474 d[2] = (ptrint) code;
3476 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3477 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3481 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3483 #if defined(ENABLE_STATISTICS)
3485 count_cstub_len += COMPILERSTUB_SIZE;
3488 /* release dump area */
3490 dump_release(dumpsize);
3496 /* createnativestub ************************************************************
3498 Creates a stub routine which calls a native method.
3500 *******************************************************************************/
3502 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3510 s4 i, j; /* count variables */
3513 s4 funcdisp; /* displacement of the function */
3515 /* get required compiler data */
3522 /* initialize variables */
3525 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3527 /* calculate stack frame size */
3529 cd->stackframesize =
3530 1 + /* return address */
3531 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3532 sizeof(localref_table) / SIZEOF_VOID_P +
3533 md->paramcount + /* for saving arguments over calls */
3534 1 + /* for saving return address */
3537 /* create method header */
3539 #if SIZEOF_VOID_P == 4
3540 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
3542 (void) dseg_addaddress(cd, code); /* MethodPointer */
3543 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
3544 (void) dseg_adds4(cd, 0); /* IsSync */
3545 (void) dseg_adds4(cd, 0); /* IsLeaf */
3546 (void) dseg_adds4(cd, 0); /* IntSave */
3547 (void) dseg_adds4(cd, 0); /* FltSave */
3548 (void) dseg_addlinenumbertablesize(cd);
3549 (void) dseg_adds4(cd, 0); /* ExTableSize */
3551 /* generate stub code */
3553 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3554 M_AST(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* store RA*/
3556 #if !defined(NDEBUG)
3557 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3558 emit_verbosecall_enter(jd);
3561 /* get function address (this must happen before the stackframeinfo) */
3563 funcdisp = dseg_addaddress(cd, f);
3565 #if !defined(WITH_STATIC_CLASSPATH)
3567 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
3569 if (opt_showdisassemble) {
3575 /* save integer and float argument registers */
3577 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3578 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3579 M_LST(rd->argintregs[i], REG_SP, j * 8);
3584 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3585 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3586 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3591 /* prepare data structures for native function call */
3593 M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, REG_A0);
3594 M_MOV(REG_PV, REG_A1);
3595 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3596 M_ALD(REG_A3, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P);
3597 disp = dseg_addaddress(cd, codegen_start_native_call);
3598 M_ALD(REG_ITMP3, REG_PV, disp);
3599 M_JSR(REG_RA, REG_ITMP3);
3600 M_NOP; /* XXX fill me! */
3602 /* restore integer and float argument registers */
3604 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3605 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3606 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3611 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3612 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3613 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3618 /* copy or spill arguments to new locations */
3620 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3621 t = md->paramtypes[i].type;
3623 if (IS_INT_LNG_TYPE(t)) {
3624 if (!md->params[i].inmemory) {
3625 s1 = rd->argintregs[md->params[i].regoff];
3627 if (!nmd->params[j].inmemory) {
3628 s2 = rd->argintregs[nmd->params[j].regoff];
3631 s2 = nmd->params[j].regoff;
3632 M_AST(s1, REG_SP, s2 * 8);
3636 s1 = md->params[i].regoff + cd->stackframesize;
3637 s2 = nmd->params[j].regoff;
3638 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
3639 M_AST(REG_ITMP1, REG_SP, s2 * 8);
3643 if (!md->params[i].inmemory) {
3644 s1 = rd->argfltregs[md->params[i].regoff];
3646 if (!nmd->params[j].inmemory) {
3647 s2 = rd->argfltregs[nmd->params[j].regoff];
3648 if (IS_2_WORD_TYPE(t))
3654 s2 = nmd->params[j].regoff;
3655 if (IS_2_WORD_TYPE(t))
3656 M_DST(s1, REG_SP, s2 * 8);
3658 M_FST(s1, REG_SP, s2 * 8);
3662 s1 = md->params[i].regoff + cd->stackframesize;
3663 s2 = nmd->params[j].regoff;
3664 if (IS_2_WORD_TYPE(t)) {
3665 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
3666 M_DST(REG_FTMP1, REG_SP, s2 * 8);
3668 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
3669 M_FST(REG_FTMP1, REG_SP, s2 * 8);
3675 /* put class into second argument register */
3677 if (m->flags & ACC_STATIC) {
3678 disp = dseg_addaddress(cd, m->class);
3679 M_ALD(REG_A1, REG_PV, disp);
3682 /* put env into first argument register */
3684 disp = dseg_addaddress(cd, _Jv_env);
3685 M_ALD(REG_A0, REG_PV, disp);
3687 /* do the native function call */
3689 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
3690 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3691 M_NOP; /* delay slot */
3693 /* save return value */
3695 if (md->returntype.type != TYPE_VOID) {
3696 if (IS_INT_LNG_TYPE(md->returntype.type))
3697 M_LST(REG_RESULT, REG_SP, 0 * 8);
3699 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3702 #if !defined(NDEBUG)
3703 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3704 emit_verbosecall_exit(jd);
3707 /* remove native stackframe info */
3709 M_AADD_IMM(REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P, REG_A0);
3710 disp = dseg_addaddress(cd, codegen_finish_native_call);
3711 M_ALD(REG_ITMP3, REG_PV, disp);
3712 M_JSR(REG_RA, REG_ITMP3);
3713 M_NOP; /* XXX fill me! */
3714 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3716 /* restore return value */
3718 if (md->returntype.type != TYPE_VOID) {
3719 if (IS_INT_LNG_TYPE(md->returntype.type))
3720 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3722 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3725 M_ALD(REG_RA, REG_SP, cd->stackframesize * 8 - SIZEOF_VOID_P); /* load RA */
3727 /* check for exception */
3729 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
3730 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
3732 M_RET(REG_RA); /* return to caller */
3733 M_NOP; /* DELAY SLOT */
3735 /* handle exception */
3737 disp = dseg_addaddress(cd, asm_handle_nat_exception);
3738 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3739 M_JMP(REG_ITMP3); /* jump to asm exception handler */
3740 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
3742 /* generate patcher stubs */
3744 emit_patcher_stubs(jd);
3748 return code->entrypoint;
3753 * These are local overrides for various environment variables in Emacs.
3754 * Please do not remove this and leave it at the end of the file, where
3755 * Emacs will automagically detect them.
3756 * ---------------------------------------------------------------------
3759 * indent-tabs-mode: t
3763 * vim:noexpandtab:sw=4:ts=4: