1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
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
33 $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
48 /* #include "vm/jit/sparc64/arch.h" */
49 #include "vm/jit/sparc64/codegen.h"
51 #include "mm/memory.h"
53 #include "native/jni.h"
54 #include "native/native.h"
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/codegen-common.h"
63 #include "vm/jit/dseg.h"
64 #include "vm/jit/emit.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/parse.h"
67 #include "vm/jit/patcher.h"
68 #include "vm/jit/reg.h"
70 /* XXX use something like this for window control ?
71 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
73 #define REG_PV REG_PV_CALLEE
75 static int fabort(char *x)
77 fprintf(stderr, "sparc64 abort because: %s\n", x);
84 /* codegen *********************************************************************
86 Generates machine code.
88 *******************************************************************************/
90 bool codegen(jitdata *jd)
96 s4 len, s1, s2, s3, d, disp;
104 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
105 builtintable_entry *bte;
107 rplpoint *replacementpoint;
109 /* get required compiler data */
116 /* prevent compiler warnings */
127 #if 0 /* no leaf optimization yet */
128 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
130 savedregs_num = 16; /* register-window save area */
133 /* space to save used callee saved registers */
135 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
136 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
138 stackframesize = rd->memuse + savedregs_num;
140 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
141 if (checksync && (m->flags & ACC_SYNCHRONIZED))
145 /* create method header */
147 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
148 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
150 #if defined(ENABLE_THREADS)
151 /* IsSync contains the offset relative to the stack pointer for the
152 argument of monitor_exit used in the exception handler. Since the
153 offset could be zero and give a wrong meaning of the flag it is
157 if (checksync && (m->flags & ACC_SYNCHRONIZED))
158 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
161 (void) dseg_adds4(cd, 0); /* IsSync */
163 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
164 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
165 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
167 dseg_addlinenumbertablesize(cd);
169 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
171 /* create exception table */
173 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
174 dseg_addtarget(cd, ex->start);
175 dseg_addtarget(cd, ex->end);
176 dseg_addtarget(cd, ex->handler);
177 (void) dseg_addaddress(cd, ex->catchtype.cls);
180 /* save register window and create stack frame (if necessary) */
183 M_SAVE(REG_SP, -stackframesize * 8, REG_SP);
185 /* save return address and used callee saved registers */
188 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
189 p--; M_DST(rd->savfltregs[i], REG_SP, (WINSAVE_REGS + p) * 8);
192 /* take arguments out of register or stack frame */
196 for (p = 0, l = 0; p < md->paramcount; p++) {
197 t = md->paramtypes[p].type;
198 var = &(rd->locals[l][t]);
200 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
204 s1 = md->params[p].regoff;
205 if (IS_INT_LNG_TYPE(t)) { /* integer args */
206 if (!md->params[p].inmemory) { /* register arguments */
207 s2 = rd->argintregs[s1];
208 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
209 M_INTMOVE(s2, var->regoff);
211 } else { /* reg arg -> spilled */
212 M_STX(s2, REG_SP, (WINSAVE_REGS + var->regoff) * 8);
215 } else { /* stack arguments */
216 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
217 M_LDX(var->regoff, REG_SP, (stackframesize + s1) * 8);
219 } else { /* stack arg -> spilled */
220 var->regoff = stackframesize + s1;
224 } else { /* floating args */
225 if (!md->params[p].inmemory) { /* register arguments */
226 s2 = rd->argfltregs[s1];
227 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
228 M_FLTMOVE(s2, var->regoff);
230 } else { /* reg arg -> spilled */
231 M_DST(s2, REG_SP, (WINSAVE_REGS + var->regoff) * 8);
234 } else { /* stack arguments */
235 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
236 M_DLD(var->regoff, REG_SP, (stackframesize + s1) * 8);
238 } else { /* stack-arg -> spilled */
239 var->regoff = stackframesize + s1;
246 /* XXX monitor enter and tracing */
250 /* end of header generation */
252 replacementpoint = jd->code->rplpoints;
254 /* walk through all basic blocks */
256 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
258 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
260 if (bptr->flags >= BBREACHED) {
262 /* branch resolving */
266 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
267 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
268 brefs->branchpos, bptr->mpc);
272 /* handle replacement points */
274 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
275 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
280 /* copy interface registers to their destination */
286 #if defined(ENABLE_LSRA)
288 while (src != NULL) {
290 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
291 /* d = reg_of_var(m, src, REG_ITMP1); */
292 if (!(src->flags & INMEMORY))
296 M_INTMOVE(REG_ITMP1, d);
297 emit_store(jd, NULL, src, d);
303 while (src != NULL) {
305 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
306 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
307 M_INTMOVE(REG_ITMP1, d);
308 emit_store(jd, NULL, src, d);
311 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
312 if ((src->varkind != STACKVAR)) {
314 if (IS_FLT_DBL_TYPE(s2)) {
315 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
316 s1 = rd->interfaces[len][s2].regoff;
319 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
321 emit_store(jd, NULL, src, d);
324 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
325 s1 = rd->interfaces[len][s2].regoff;
328 M_LDX(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
330 emit_store(jd, NULL, src, d);
336 #if defined(ENABLE_LSRA)
340 /* walk through all instructions */
345 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
346 if (iptr->line != currentline) {
347 dseg_addlinenumber(cd, iptr->line);
348 currentline = iptr->line;
351 MCODECHECK(64); /* an instruction usually needs < 64 words */
354 case ICMD_INLINE_START:
355 case ICMD_INLINE_END:
358 case ICMD_NOP: /* ... ==> ... */
361 /* constant operations ************************************************/
363 case ICMD_ICONST: /* ... ==> ..., constant */
365 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
366 ICONST(d, iptr->sx.val.i);
367 emit_store_dst(jd, iptr, d);
370 case ICMD_LCONST: /* ... ==> ..., constant */
372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
373 LCONST(d, iptr->sx.val.l);
374 emit_store_dst(jd, iptr, d);
377 case ICMD_FCONST: /* ... ==> ..., constant */
379 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
380 disp = dseg_addfloat(cd, iptr->sx.val.f);
381 M_FLD(d, REG_PV, disp);
382 emit_store_dst(jd, iptr, d);
385 case ICMD_DCONST: /* ... ==> ..., constant */
387 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
388 disp = dseg_adddouble(cd, iptr->sx.val.d);
389 M_DLD(d, REG_PV, disp);
390 emit_store_dst(jd, iptr, d);
393 case ICMD_ACONST: /* ... ==> ..., constant */
395 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
397 if ((iptr->target != NULL) && (iptr->sx.val.anyptr == NULL)) {
398 disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
400 codegen_addpatchref(cd, PATCHER_aconst,
401 (unresolved_class *) iptr->target, disp);
403 if (opt_showdisassemble) {
407 M_ALD(REG_PV, disp, d);
410 if (iptr->sx.val.anyptr == NULL) {
411 M_INTMOVE(REG_ZERO, d);
413 disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
414 M_ALD(d, REG_PV, disp);
417 emit_store_dst(jd, iptr, d);
421 /* load/store operations **********************************************/
423 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
424 case ICMD_LLOAD: /* op1 = local variable */
427 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
428 if ((iptr->dst.var->varkind == LOCALVAR) &&
429 (iptr->dst.var->varnum == iptr->s1.localindex))
431 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
432 if (var->flags & INMEMORY) {
433 M_ALD(REG_SP, var->regoff * 8, d);
435 M_INTMOVE(var->regoff, d);
437 emit_store_dst(jd, iptr, d);
440 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
441 case ICMD_DLOAD: /* op1 = local variable */
443 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
444 if ((iptr->dst.var->varkind == LOCALVAR) &&
445 (iptr->dst.var->varnum == iptr->s1.localindex))
447 var = &(rd->locals[iptr->s1.localindex][iptr->opc - ICMD_ILOAD]);
448 if (var->flags & INMEMORY) {
449 M_DLD(d, REG_SP, var->regoff * 8);
451 M_FLTMOVE(var->regoff, d);
453 emit_store_dst(jd, iptr, d);
457 case ICMD_ISTORE: /* ..., value ==> ... */
458 case ICMD_LSTORE: /* op1 = local variable */
461 if ((iptr->s1.var->varkind == LOCALVAR) &&
462 (iptr->s1.var->varnum == iptr->dst.localindex))
464 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
465 if (var->flags & INMEMORY) {
466 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
467 M_STX(s1, REG_SP, var->regoff * 8);
469 s1 = emit_load_s1(jd, iptr, var->regoff);
470 M_INTMOVE(s1, var->regoff);
474 case ICMD_FSTORE: /* ..., value ==> ... */
475 case ICMD_DSTORE: /* op1 = local variable */
477 if ((iptr->s1.var->varkind == LOCALVAR) &&
478 (iptr->s1.var->varnum == iptr->dst.localindex))
480 var = &(rd->locals[iptr->dst.localindex][iptr->opc - ICMD_ISTORE]);
481 if (var->flags & INMEMORY) {
482 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
483 M_DST(s1, REG_SP, var->regoff * 8);
485 s1 = emit_load_s1(jd, iptr, var->regoff);
486 M_FLTMOVE(s1, var->regoff);
491 /* pop/dup/swap operations ********************************************/
493 /* attention: double and longs are only one entry in CACAO ICMDs */
495 case ICMD_POP: /* ..., value ==> ... */
496 case ICMD_POP2: /* ..., value, value ==> ... */
499 case ICMD_DUP: /* ..., a ==> ..., a, a */
500 M_COPY(src, iptr->dst);
503 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
505 M_COPY(src, iptr->dst);
506 M_COPY(src->prev, iptr->dst->prev);
507 M_COPY(iptr->dst, iptr->dst->prev->prev);
510 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
512 M_COPY(src, iptr->dst);
513 M_COPY(src->prev, iptr->dst->prev);
514 M_COPY(src->prev->prev, iptr->dst->prev->prev);
515 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
518 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
520 M_COPY(src, iptr->dst);
521 M_COPY(src->prev, iptr->dst->prev);
524 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
526 M_COPY(src, iptr->dst);
527 M_COPY(src->prev, iptr->dst->prev);
528 M_COPY(src->prev->prev, iptr->dst->prev->prev);
529 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
530 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
533 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
535 M_COPY(src, iptr->dst);
536 M_COPY(src->prev, iptr->dst->prev);
537 M_COPY(src->prev->prev, iptr->dst->prev->prev);
538 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
539 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
540 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
543 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
545 M_COPY(src, iptr->dst->prev);
546 M_COPY(src->prev, iptr->dst);
550 /* integer operations *************************************************/
552 case ICMD_INEG: /* ..., value ==> ..., - value */
555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
556 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
557 M_SUB(REG_ZERO, s1, d);
558 emit_store_dst(jd, iptr, d);
561 case ICMD_I2L: /* ..., value ==> ..., value */
563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
566 emit_store_dst(jd, iptr, d);
569 case ICMD_L2I: /* ..., value ==> ..., value */
571 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
573 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
574 emit_store_dst(jd, iptr, d);
577 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
579 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
580 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
581 M_SLLX_IMM(s1, 56, d);
582 M_SRAX_IMM( d, 56, d);
583 emit_store_dst(jd, iptr, d);
586 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
590 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
591 M_SLLX_IMM(s1, 48, d);
592 M_SRAX_IMM( d, 48, d);
593 emit_store_dst(jd, iptr, d);
596 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 emit_store_dst(jd, iptr, d);
606 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
607 /* sx.val.i = constant */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
612 M_ADD_IMM(s1, iptr->sx.val.i, d);
614 ICONST(REG_ITMP2, iptr->sx.val.i);
615 M_ADD(s1, REG_ITMP2, d);
617 emit_store_dst(jd, iptr, d);
620 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
621 /* sx.val.l = constant */
623 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
624 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
625 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
626 M_ADD_IMM(s1, iptr->sx.val.l, d);
628 LCONST(REG_ITMP2, iptr->sx.val.l);
629 M_ADD(s1, REG_ITMP2, d);
631 emit_store_dst(jd, iptr, d);
634 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 emit_store_dst(jd, iptr, d);
644 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
645 /* sx.val.i = constant */
647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
649 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
650 M_SUB_IMM(s1, iptr->sx.val.i, d);
652 ICONST(REG_ITMP2, iptr->sx.val.i);
653 M_SUB(s1, REG_ITMP2, d);
655 emit_store_dst(jd, iptr, d);
658 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
659 /* sx.val.l = constant */
661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
663 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
664 M_SUB_IMM(s1, iptr->sx.val.l, d);
666 LCONST(REG_ITMP2, iptr->sx.val.l);
667 M_SUB(s1, REG_ITMP2, d);
669 emit_store_dst(jd, iptr, d);
672 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
676 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
679 emit_store_dst(jd, iptr, d);
682 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
683 /* sx.val.i = constant */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
687 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
688 M_MULX_IMM(s1, iptr->sx.val.i, d);
690 ICONST(REG_ITMP2, iptr->sx.val.i);
691 M_MULX(s1, REG_ITMP2, d);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
697 /* sx.val.l = constant */
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
701 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
702 M_MULX_IMM(s1, iptr->sx.val.l, d);
704 LCONST(REG_ITMP2, iptr->sx.val.l);
705 M_MULX(s1, REG_ITMP2, d);
707 emit_store_dst(jd, iptr, d);
710 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
711 /* XXX could also clear Y and use 32bit div */
712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
717 /* XXX trim s2 like s1 ? */
719 emit_store_dst(jd, iptr, d);
722 case ICMD_LDIV: /* ..., 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_ITMP2);
729 emit_store_dst(jd, iptr, d);
732 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
736 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
739 /* XXX trim s2 like s1 ? */
743 emit_store_dst(jd, iptr, d);
746 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
748 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
749 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
750 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
755 emit_store_dst(jd, iptr, d);
758 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
759 case ICMD_LDIVPOW2: /* val.i = constant */
761 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
763 M_SRAX_IMM(s1, 63, REG_ITMP2);
764 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
765 M_ADD(s1, REG_ITMP2, REG_ITMP2);
766 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
767 emit_store_dst(jd, iptr, d);
770 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
774 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
777 emit_store_dst(jd, iptr, d);
780 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
781 case ICMD_LSHLCONST: /* val.i = constant */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785 M_SLLX_IMM(s1, iptr->sx.val.i, d);
786 emit_store_dst(jd, iptr, d);
789 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
792 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
795 emit_store_dst(jd, iptr, d);
798 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
799 /* sx.val.i = constant */
801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
802 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
803 M_SRA_IMM(s1, iptr->sx.val.i, d);
804 emit_store_dst(jd, iptr, d);
807 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
809 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
810 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
811 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813 emit_store_dst(jd, iptr, d);
816 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
817 /* sx.val.i = constant */
819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
821 M_SRL_IMM(s1, iptr->sx.val.i, d);
822 emit_store_dst(jd, iptr, d);
825 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
827 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
828 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
829 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
831 emit_store_dst(jd, iptr, d);
834 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
835 /* sx.val.i = constant */
837 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
838 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
839 M_SRAX_IMM(s1, iptr->sx.val.i, d);
840 emit_store_dst(jd, iptr, d);
843 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
847 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
849 emit_store_dst(jd, iptr, d);
852 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
853 /* sx.val.i = constant */
855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
856 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
857 M_SRLX_IMM(s1, iptr->sx.val.i, d);
858 emit_store_dst(jd, iptr, d);
861 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 emit_store_dst(jd, iptr, d);
871 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
872 /* sx.val.i = constant */
874 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
875 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
877 M_AND_IMM(s1, iptr->sx.val.i, d);
879 ICONST(REG_ITMP2, iptr->sx.val.i);
880 M_AND(s1, REG_ITMP2, d);
882 emit_store_dst(jd, iptr, d);
885 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
886 /* sx.val.i = constant */
888 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
889 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
890 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
892 M_MOV(s1, REG_ITMP1);
895 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
896 M_AND_IMM(s1, iptr->sx.val.i, d);
899 M_SUB(REG_ZERO, s1, d);
900 M_AND_IMM(d, iptr->sx.val.i, d);
902 ICONST(REG_ITMP2, iptr->sx.val.i);
903 M_AND(s1, REG_ITMP2, d);
906 M_SUB(REG_ZERO, s1, d);
907 M_AND(d, REG_ITMP2, d);
909 M_SUB(REG_ZERO, d, d);
910 emit_store_dst(jd, iptr, d);
913 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
914 /* sx.val.l = constant */
916 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
917 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
918 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
919 M_AND_IMM(s1, iptr->sx.val.l, d);
921 LCONST(REG_ITMP2, iptr->sx.val.l);
922 M_AND(s1, REG_ITMP2, d);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
928 /* sx.val.l = constant */
930 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
933 M_MOV(s1, REG_ITMP1);
936 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
937 M_AND_IMM(s1, iptr->sx.val.l, d);
940 M_SUB(REG_ZERO, s1, d);
941 M_AND_IMM(d, iptr->sx.val.l, d);
943 LCONST(REG_ITMP2, iptr->sx.val.l);
944 M_AND(s1, REG_ITMP2, d);
947 M_SUB(REG_ZERO, s1, d);
948 M_AND(d, REG_ITMP2, d);
950 M_SUB(REG_ZERO, d, d);
951 emit_store_dst(jd, iptr, d);
954 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
958 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
959 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
961 emit_store_dst(jd, iptr, d);
964 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
965 /* sx.val.i = constant */
967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
968 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
969 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
970 M_OR_IMM(s1, iptr->sx.val.i, d);
972 ICONST(REG_ITMP2, iptr->sx.val.i);
973 M_OR(s1, REG_ITMP2, d);
975 emit_store_dst(jd, iptr, d);
978 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
979 /* sx.val.l = constant */
981 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
982 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
983 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
984 M_OR_IMM(s1, iptr->sx.val.l, d);
986 LCONST(REG_ITMP2, iptr->sx.val.l);
987 M_OR(s1, REG_ITMP2, d);
989 emit_store_dst(jd, iptr, d);
992 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
996 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
997 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
999 emit_store_dst(jd, iptr, d);
1002 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1003 /* sx.val.i = constant */
1005 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1006 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1007 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1008 M_XOR_IMM(s1, iptr->sx.val.i, d);
1010 ICONST(REG_ITMP2, iptr->sx.val.i);
1011 M_XOR(s1, REG_ITMP2, d);
1013 emit_store_dst(jd, iptr, d);
1016 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1017 /* sx.val.l = constant */
1019 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1020 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1021 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1022 M_XOR_IMM(s1, iptr->sx.val.l, d);
1024 LCONST(REG_ITMP2, iptr->sx.val.l);
1025 M_XOR(s1, REG_ITMP2, d);
1027 emit_store_dst(jd, iptr, d);
1031 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1035 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1038 M_XCMOVLT_IMM(-1, d);
1039 M_XCMOVGT_IMM(1, d);
1040 emit_store_dst(jd, iptr, d);
1044 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1045 /* s1.localindex = variable, sx.val.i = constant */
1047 var = &(rd->locals[iptr->s1.localindex][TYPE_INT]);
1048 if (var->flags & INMEMORY) {
1050 M_LDX(s1, REG_SP, var->regoff * 8);
1053 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1054 M_ADD_IMM(s1, iptr->sx.val.i, s1);
1056 ICONST(REG_ITMP2, iptr->sx.val.i);
1057 M_ADD(s1, REG_ITMP2, s1);
1059 if (var->flags & INMEMORY)
1060 M_STX(s1, REG_SP, var->regoff * 8);
1064 /* floating operations ************************************************/
1066 case ICMD_FNEG: /* ..., value ==> ..., - value */
1068 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1069 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1071 emit_store_dst(jd, iptr, d);
1074 case ICMD_DNEG: /* ..., value ==> ..., - value */
1076 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1077 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1079 emit_store_dst(jd, iptr, d);
1082 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1084 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1085 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1086 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1093 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1094 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1095 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1097 emit_store_dst(jd, iptr, d);
1100 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1102 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1103 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1104 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1106 emit_store_dst(jd, iptr, d);
1109 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1111 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1112 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1113 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1115 emit_store_dst(jd, iptr, d);
1118 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1120 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1121 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1122 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1124 emit_store_dst(jd, iptr, d);
1127 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1129 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1130 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1131 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1133 emit_store_dst(jd, iptr, d);
1136 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1138 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1139 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1140 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1142 emit_store_dst(jd, iptr, d);
1145 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1147 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1148 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1149 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1151 emit_store_dst(jd, iptr, d);
1155 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1156 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1157 disp = dseg_addfloat(cd, 0.0);
1158 M_IST (s1, REG_PV_CALLEE, disp);
1159 M_FLD (d, REG_PV_CALLEE, disp);
1160 M_CVTIF (d, d); /* rd gets translated to double target register */
1161 emit_store_dst(jd, iptr, d);
1165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1166 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1167 disp = dseg_adddouble(cd, 0.0);
1168 M_STX (s1, REG_PV_CALLEE, disp);
1169 M_DLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1170 M_CVTLF (REG_FTMP2, d); /* rd gets translated to double target register */
1171 emit_store_dst(jd, iptr, d);
1174 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1175 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1176 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1177 disp = dseg_addfloat(cd, 0.0);
1178 M_CVTFI(s1, REG_FTMP2);
1179 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1180 M_ILD(d, REG_PV, disp);
1181 emit_store_dst(jd, iptr, d);
1185 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1186 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1187 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1188 disp = dseg_addfloat(cd, 0.0);
1189 M_CVTDI(s1, REG_FTMP2);
1190 M_FST(REG_FTMP2, REG_PV, disp);
1191 M_ILD(d, REG_PV, disp);
1192 emit_store_dst(jd, iptr, d);
1195 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1196 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1197 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1198 disp = dseg_adddouble(cd, 0.0);
1199 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1200 M_DST(REG_FTMP2, REG_PV, disp);
1201 M_LDX(d, REG_PV, disp);
1202 emit_store_dst(jd, iptr, d);
1205 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1206 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1207 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1208 disp = dseg_adddouble(cd, 0.0);
1209 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1210 M_DST(REG_FTMP2, REG_PV, disp);
1211 M_LDX(d, REG_PV, disp);
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1217 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1218 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1220 emit_store_dst(jd, iptr, d);
1223 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1225 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1226 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1228 emit_store_dst(jd, iptr, d);
1231 /* XXX merge F/D versions? only compare instr. is different */
1232 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1234 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1235 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1236 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1238 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1239 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1240 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1241 emit_store_dst(jd, iptr, d);
1244 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1246 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1247 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1248 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1250 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1251 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1252 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1258 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1259 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1260 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1262 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1263 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1264 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1270 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1271 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1272 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1274 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1275 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1276 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1277 emit_store_dst(jd, iptr, d);
1281 /* memory operations **************************************************/
1283 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1285 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1286 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1287 gen_nullptr_check(s1);
1288 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1289 emit_store_dst(jd, iptr, d);
1292 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1294 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1295 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1296 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1297 if (INSTRUCTION_MUST_CHECK(iptr)) {
1298 gen_nullptr_check(s1);
1301 M_AADD(s2, s1, REG_ITMP3);
1302 M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1303 emit_store_dst(jd, iptr, d);
1306 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1309 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1310 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1311 if (INSTRUCTION_MUST_CHECK(iptr)) {
1312 gen_nullptr_check(s1);
1315 M_AADD(s2, s1, REG_ITMP3);
1316 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1317 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1326 if (INSTRUCTION_MUST_CHECK(iptr)) {
1327 gen_nullptr_check(s1);
1330 M_AADD(s2, s1, REG_ITMP3);
1331 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1332 M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1333 emit_store_dst(jd, iptr, d);
1336 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1339 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1341 if (INSTRUCTION_MUST_CHECK(iptr)) {
1342 gen_nullptr_check(s1);
1345 M_ASLL_IMM(s2, 2, REG_ITMP3);
1346 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1347 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1348 emit_store_dst(jd, iptr, d);
1351 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1354 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1355 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1356 if (INSTRUCTION_MUST_CHECK(iptr)) {
1357 gen_nullptr_check(s1);
1360 M_ASLL_IMM(s2, 3, REG_ITMP3);
1361 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1362 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1363 emit_store_dst(jd, iptr, d);
1366 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1369 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1370 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1371 if (INSTRUCTION_MUST_CHECK(iptr)) {
1372 gen_nullptr_check(s1);
1375 M_ASLL_IMM(s2, 2, REG_ITMP3);
1376 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1377 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1378 emit_store_dst(jd, iptr, d);
1381 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1383 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1384 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1385 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1386 if (INSTRUCTION_MUST_CHECK(iptr)) {
1387 gen_nullptr_check(s1);
1390 M_ASLL_IMM(s2, 3, REG_ITMP3);
1391 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1392 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1393 emit_store_dst(jd, iptr, d);
1396 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1399 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1400 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1401 if (INSTRUCTION_MUST_CHECK(iptr)) {
1402 gen_nullptr_check(s1);
1405 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1406 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1407 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1408 emit_store_dst(jd, iptr, d);
1412 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1414 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1415 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1416 if (INSTRUCTION_MUST_CHECK(iptr)) {
1417 gen_nullptr_check(s1);
1420 M_AADD(s2, s1, REG_ITMP1);
1421 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1422 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1425 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1426 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1428 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1429 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1430 if (INSTRUCTION_MUST_CHECK(iptr)) {
1431 gen_nullptr_check(s1);
1434 M_AADD(s2, s1, REG_ITMP1);
1435 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1436 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1437 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1440 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1442 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1443 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1444 if (INSTRUCTION_MUST_CHECK(iptr)) {
1445 gen_nullptr_check(s1);
1448 M_ASLL_IMM(s2, 2, REG_ITMP2);
1449 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1450 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1451 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1454 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1456 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1457 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1458 if (INSTRUCTION_MUST_CHECK(iptr)) {
1459 gen_nullptr_check(s1);
1462 M_ASLL_IMM(s2, 3, REG_ITMP2);
1463 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1464 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1465 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1468 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1470 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1471 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1472 if (INSTRUCTION_MUST_CHECK(iptr)) {
1473 gen_nullptr_check(s1);
1476 M_ASLL_IMM(s2, 2, REG_ITMP2);
1477 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1478 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1479 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1482 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1485 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1486 if (INSTRUCTION_MUST_CHECK(iptr)) {
1487 gen_nullptr_check(s1);
1490 M_ASLL_IMM(s2, 3, REG_ITMP2);
1491 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1492 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1493 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1497 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1500 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1501 if (INSTRUCTION_MUST_CHECK(iptr)) {
1502 gen_nullptr_check(s1);
1505 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1507 M_MOV(s1, rd->argintregs[0]);
1508 M_MOV(s3, rd->argintregs[1]);
1509 disp = dseg_addaddress(cd, BUILTIN_canstore);
1510 M_ALD(REG_ITMP3, REG_PV, disp);
1511 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1514 M_BEQZ(REG_RESULT_CALLER, 0);
1515 codegen_add_arraystoreexception_ref(cd);
1518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1519 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1520 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1521 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1522 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1523 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1527 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1530 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1531 if (INSTRUCTION_MUST_CHECK(iptr)) {
1532 gen_nullptr_check(s1);
1535 M_AADD(s2, s1, REG_ITMP1);
1536 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1539 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1540 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1543 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1544 if (INSTRUCTION_MUST_CHECK(iptr)) {
1545 gen_nullptr_check(s1);
1548 M_AADD(s2, s1, REG_ITMP1);
1549 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1550 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1553 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1556 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1557 if (INSTRUCTION_MUST_CHECK(iptr)) {
1558 gen_nullptr_check(s1);
1561 M_ASLL_IMM(s2, 2, REG_ITMP2);
1562 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1563 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1566 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1568 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1569 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1570 if (INSTRUCTION_MUST_CHECK(iptr)) {
1571 gen_nullptr_check(s1);
1574 M_ASLL_IMM(s2, 3, REG_ITMP2);
1575 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1576 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1579 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1582 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1583 if (INSTRUCTION_MUST_CHECK(iptr)) {
1584 gen_nullptr_check(s1);
1587 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1588 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1589 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1593 case ICMD_GETSTATIC: /* ... ==> ..., value */
1595 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1596 unresolved_field *uf = iptr->sx.s23.s3.uf;
1598 fieldtype = uf->fieldref->parseddesc.fd->type;
1600 disp = dseg_addaddress(cd, NULL);
1602 codegen_addpatchref(cd, PATCHER_get_putstatic,
1603 iptr->sx.s23.s3.uf, disp);
1605 if (opt_showdisassemble) {
1610 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1612 disp = dseg_addaddress(cd, &(fi->value));
1614 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1615 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1617 if (opt_showdisassemble) {
1623 M_ALD(REG_ITMP1, REG_PV, disp);
1624 switch (fieldtype) {
1626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1627 M_ILD_INTERN(d, REG_ITMP1, 0);
1628 emit_store_dst(jd, iptr, d);
1631 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1632 M_LDX_INTERN(d, REG_ITMP1, 0);
1633 emit_store_dst(jd, iptr, d);
1636 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1637 M_ALD_INTERN(d, REG_ITMP1, 0);
1638 emit_store_dst(jd, iptr, d);
1641 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1642 M_FLD_INTERN(d, REG_ITMP1, 0);
1643 emit_store_dst(jd, iptr, d);
1646 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1647 M_DLD_INTERN(d, REG_ITMP1, 0);
1648 emit_store_dst(jd, iptr, d);
1653 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1655 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1656 unresolved_field *uf = iptr->sx.s23.s3.uf;
1658 fieldtype = uf->fieldref->parseddesc.fd->type;
1660 disp = dseg_addaddress(cd, NULL);
1662 codegen_addpatchref(cd, PATCHER_get_putstatic,
1663 iptr->sx.s23.s3.uf, disp);
1665 if (opt_showdisassemble) {
1670 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1672 disp = dseg_addaddress(cd, &(fi->value));
1674 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1675 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1677 if (opt_showdisassemble) {
1683 M_ALD(REG_ITMP1, REG_PV, disp);
1684 switch (fieldtype) {
1686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1687 M_IST_INTERN(s2, REG_ITMP1, 0);
1690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1691 M_STX_INTERN(s2, REG_ITMP1, 0);
1694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1695 M_AST_INTERN(s2, REG_ITMP1, 0);
1698 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1699 M_FST_INTERN(s2, REG_ITMP1, 0);
1702 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1703 M_DST_INTERN(s2, REG_ITMP1, 0);
1708 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1709 /* val = value (in current instruction) */
1710 /* following NOP) */
1712 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1713 unresolved_field *uf = iptr->sx.s23.s3.uf;
1715 fieldtype = uf->fieldref->parseddesc.fd->type;
1717 disp = dseg_addaddress(cd, NULL);
1719 codegen_addpatchref(cd, PATCHER_get_putstatic,
1722 if (opt_showdisassemble) {
1727 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1729 fieldtype = fi->type;
1732 disp = dseg_addaddress(cd, &(fi->value));
1734 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1735 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1737 if (opt_showdisassemble) {
1743 M_ALD(REG_ITMP1, REG_PV, disp);
1744 switch (fieldtype) {
1746 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1749 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1752 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1755 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1758 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1764 case ICMD_GETFIELD: /* ... ==> ..., value */
1766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1767 gen_nullptr_check(s1);
1769 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1770 unresolved_field *uf = iptr->sx.s23.s3.uf;
1772 fieldtype = uf->fieldref->parseddesc.fd->type;
1774 codegen_addpatchref(cd, PATCHER_get_putfield,
1775 iptr->sx.s23.s3.uf, 0);
1777 if (opt_showdisassemble) {
1784 disp = iptr->sx.s23.s3.fmiref->p.field->offset;
1787 switch (fieldtype) {
1789 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1791 emit_store_dst(jd, iptr, d);
1794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1796 emit_store_dst(jd, iptr, d);
1799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1801 emit_store_dst(jd, iptr, d);
1804 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1806 emit_store_dst(jd, iptr, d);
1809 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1811 emit_store_dst(jd, iptr, d);
1816 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1818 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1819 gen_nullptr_check(s1);
1821 /*if (!IS_FLT_DBL_TYPE(fieldtype)) {
1822 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1824 s2 = emit_load_s2(jd, iptr, REG_IFTMP);
1827 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1828 unresolved_field *uf = iptr->sx.s23.s3.uf;
1830 fieldtype = uf->fieldref->parseddesc.fd->type;
1832 codegen_addpatchref(cd, PATCHER_get_putfield,
1833 iptr->sx.s23.s3.uf, 0);
1835 if (opt_showdisassemble) {
1842 disp = iptr->sx.s23.s3.fmiref->p.field->offset;
1845 switch (fieldtype) {
1847 M_IST(s2, s1, disp);
1850 M_STX(s2, s1, disp);
1853 M_AST(s2, s1, disp);
1856 M_FST(s2, s1, disp);
1859 M_DST(s2, s1, disp);
1864 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1865 /* val = value (in current instruction) */
1866 /* following NOP) */
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1869 gen_nullptr_check(s1);
1871 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1872 unresolved_field *uf = iptr->sx.s23.s3.uf;
1874 fieldtype = uf->fieldref->parseddesc.fd->type;
1876 codegen_addpatchref(cd, PATCHER_get_putfield,
1879 if (opt_showdisassemble) {
1887 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1889 fieldtype = fi->type;
1895 switch (fieldtype) {
1897 M_IST(REG_ZERO, s1, disp);
1900 M_STX(REG_ZERO, s1, disp);
1903 M_AST(REG_ZERO, s1, disp);
1906 M_FST(REG_ZERO, s1, disp);
1909 M_DST(REG_ZERO, s1, disp);
1915 /* branch operations **************************************************/
1917 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1920 M_INTMOVE(s1, REG_ITMP2_XPTR);
1922 #ifdef ENABLE_VERIFIER
1923 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1924 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1925 iptr->sx.s23.s2.uc, 0);
1927 if (opt_showdisassemble)
1930 #endif /* ENABLE_VERIFIER */
1932 disp = dseg_addaddress(cd, asm_handle_exception);
1933 M_ALD(REG_ITMP2, REG_PV, disp);
1934 M_JMP(REG_ITMP3_XPC, REG_ITMP2, REG_ZERO);
1936 M_NOP; /* nop ensures that XPC is less than the end */
1937 /* of basic block */
1941 case ICMD_GOTO: /* ... ==> ... */
1943 codegen_addreference(cd, iptr->dst.block);
1948 case ICMD_JSR: /* ... ==> ... */
1950 dseg_addtarget(cd, iptr->sx.s23.s3.jsrtarget.block);
1951 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
1952 M_JMP(REG_ITMP1, REG_ITMP1, REG_ZERO); /* REG_ITMP1 = return address */
1956 case ICMD_RET: /* ... ==> ... */
1957 /* s1.localindex = local variable */
1958 var = &(rd->locals[iptr->s1.localindex][TYPE_ADR]);
1959 if (var->flags & INMEMORY) {
1960 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
1968 case ICMD_IFNULL: /* ..., value ==> ... */
1970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1972 codegen_addreference(cd, iptr->dst.block);
1976 case ICMD_IFNONNULL: /* ..., value ==> ... */
1978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1980 codegen_addreference(cd, iptr->dst.block);
1984 case ICMD_IFEQ: /* ..., value ==> ... */
1986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 if (iptr->sx.val.i == 0) {
1990 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1991 M_CMP_IMM(s1, iptr->sx.val.i);
1994 ICONST(REG_ITMP2, iptr->sx.val.i);
1995 M_CMP(s1, REG_ITMP2);
1999 codegen_addreference(cd, iptr->dst.block);
2003 case ICMD_IFLT: /* ..., value ==> ... */
2005 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2006 if (iptr->sx.val.i == 0) {
2009 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2010 M_CMP_IMM(s1, iptr->sx.val.i);
2012 ICONST(REG_ITMP2, iptr->sx.val.i);
2013 M_CMP(s1, REG_ITMP2);
2017 codegen_addreference(cd, iptr->dst.block);
2021 case ICMD_IFLE: /* ..., value ==> ... */
2023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2024 if (iptr->sx.val.i == 0) {
2028 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2029 M_CMP_IMM(s1, iptr->sx.val.i);
2032 ICONST(REG_ITMP2, iptr->sx.val.i);
2033 M_CMP(s1, REG_ITMP2);
2037 codegen_addreference(cd, iptr->dst.block);
2041 case ICMD_IFNE: /* ..., value ==> ... */
2043 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2044 if (iptr->sx.val.i == 0) {
2048 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
2049 M_CMP_IMM(s1, iptr->sx.val.i);
2052 ICONST(REG_ITMP2, iptr->sx.val.i);
2053 M_CMP(s1, REG_ITMP2);
2057 codegen_addreference(cd, iptr->dst.block);
2061 case ICMD_IFGT: /* ..., value ==> ... */
2062 /* op1 = target JavaVM pc, val.i = constant */
2064 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2065 if (iptr->val.i == 0) {
2068 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
2069 M_CMP_IMM(s1, iptr->val.i);
2071 ICONST(REG_ITMP2, iptr->val.i);
2072 M_CMP(s1, REG_ITMP2);
2076 codegen_addreference(cd, (basicblock *) iptr->target);
2080 case ICMD_IFGE: /* ..., value ==> ... */
2081 /* op1 = target JavaVM pc, val.i = constant */
2083 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2084 if (iptr->val.i == 0) {
2088 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
2089 M_CMP_IMM(s1, iptr->val.i);
2092 ICONST(REG_ITMP2, iptr->val.i);
2093 M_CMP(s1, REG_ITMP2);
2097 codegen_addreference(cd, (basicblock *) iptr->target);
2101 case ICMD_IF_LEQ: /* ..., value ==> ... */
2102 /* op1 = target JavaVM pc, val.l = constant */
2104 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2105 if (iptr->val.l == 0) {
2109 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
2110 M_CMP_IMM(s1, iptr->val.l);
2113 LCONST(REG_ITMP2, iptr->val.l);
2114 M_CMP(s1, REG_ITMP2);
2118 codegen_addreference(cd, (basicblock *) iptr->target);
2122 case ICMD_IF_LLT: /* ..., value ==> ... */
2123 /* op1 = target JavaVM pc, val.l = constant */
2125 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2126 if (iptr->val.l == 0) {
2129 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
2130 M_CMP_IMM(s1, iptr->val.l);
2132 ICONST(REG_ITMP2, iptr->val.l);
2133 M_CMP(s1, REG_ITMP2);
2137 codegen_addreference(cd, (basicblock *) iptr->target);
2141 case ICMD_IF_LLE: /* ..., value ==> ... */
2142 /* op1 = target JavaVM pc, val.l = constant */
2144 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2145 if (iptr->val.l == 0) {
2149 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
2150 M_CMP_IMM(s1, iptr->val.l);
2153 ICONST(REG_ITMP2, iptr->val.l);
2154 M_CMP(s1, REG_ITMP2);
2158 codegen_addreference(cd, (basicblock *) iptr->target);
2162 case ICMD_IF_LNE: /* ..., value ==> ... */
2163 /* op1 = target JavaVM pc, val.l = constant */
2165 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2166 if (iptr->val.l == 0) {
2170 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
2171 M_CMP_IMM(s1, iptr->val.i);
2174 ICONST(REG_ITMP2, iptr->val.l);
2175 M_CMP(s1, REG_ITMP2);
2179 codegen_addreference(cd, (basicblock *) iptr->target);
2183 case ICMD_IF_LGT: /* ..., value ==> ... */
2184 /* op1 = target JavaVM pc, val.l = constant */
2186 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2187 if (iptr->val.l == 0) {
2190 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
2191 M_CMP_IMM(s1, iptr->val.l);
2193 ICONST(REG_ITMP2, iptr->val.l);
2194 M_CMP(s1, REG_ITMP2);
2198 codegen_addreference(cd, (basicblock *) iptr->target);
2202 case ICMD_IF_LGE: /* ..., value ==> ... */
2203 /* op1 = target JavaVM pc, val.l = constant */
2205 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2206 if (iptr->val.l == 0) {
2210 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
2211 M_CMP_IMM(s1, iptr->val.l);
2214 ICONST(REG_ITMP2, iptr->val.l);
2215 M_CMP(s1, REG_ITMP2);
2219 codegen_addreference(cd, (basicblock *) iptr->target);
2224 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2225 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2227 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2228 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2231 codegen_addreference(cd, iptr->dst.block);
2235 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2237 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2238 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2241 codegen_addreference(cd, iptr->dst.block);
2245 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2246 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2249 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2252 codegen_addreference(cd, iptr->dst.block);
2256 case ICMD_IF_ICMPNE: /* 32-bit compare */
2258 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2259 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2262 codegen_addreference(cd, iptr->dst.block);
2266 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2272 codegen_addreference(cd, iptr->dst.block);
2276 case ICMD_IF_ICMPLT: /* 32-bit compare */
2278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2279 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2282 codegen_addreference(cd, iptr->dst.block);
2286 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2289 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2292 codegen_addreference(cd, iptr->dst.block);
2296 case ICMD_IF_ICMPGT: /* 32-bit compare */
2298 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2299 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2302 codegen_addreference(cd, iptr->dst.block);
2306 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2309 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2312 codegen_addreference(cd, iptr->dst.block);
2316 case ICMD_IF_ICMPLE: /* 32-bit compare */
2318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2319 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2322 codegen_addreference(cd, iptr->dst.block);
2327 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2330 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2333 codegen_addreference(cd, iptr->dst.block);
2337 case ICMD_IF_ICMPGE: /* 32-bit compare */
2339 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2340 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2343 codegen_addreference(cd, iptr->dst.block);
2348 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2351 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2352 M_INTMOVE(s1, REG_RESULT_CALLEE);
2353 goto nowperformreturn;
2355 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2357 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2358 M_INTMOVE(s1, REG_RESULT_CALLEE);
2360 #ifdef ENABLE_VERIFIER
2361 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2362 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2363 iptr->sx.s23.s2.uc, 0);
2365 if (opt_showdisassemble)
2368 #endif /* ENABLE_VERIFIER */
2369 goto nowperformreturn;
2371 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2374 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2375 M_FLTMOVE(s1, REG_FRESULT);
2376 goto nowperformreturn;
2378 case ICMD_RETURN: /* ... ==> ... */
2386 /* call trace function */
2388 #if !defined(NDEBUG)
2389 if (opt_verbosecall) {
2390 M_LDA(REG_SP, REG_SP, -3 * 8);
2391 M_AST(REG_RA_CALLEE, REG_SP, 0 * 8); /* XXX: no need to save anything but FRES ? */
2392 /* M_STX(REG_RESULT, REG_SP, 1 * 8); */
2393 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2395 disp = dseg_addaddress(cd, m);
2396 M_ALD(rd->argintregs[0], REG_PV, disp);
2397 M_MOV(REG_RESULT_CALLEE, rd->argintregs[1]);
2398 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2399 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2401 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2402 M_ALD(REG_ITMP3, REG_PV, disp);
2403 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2406 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2407 /* M_LDX(REG_RESULT, REG_SP, 1 * 8); */
2408 M_ALD(REG_RA_CALLEE, REG_SP, 0 * 8);
2409 M_LDA(REG_SP, REG_SP, 3 * 8);
2413 #if defined(ENABLE_THREADS)
2414 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2415 /* XXX: REG_RESULT is save, but what about FRESULT? */
2416 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2418 switch (iptr->opc) {
2421 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2425 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2426 M_ALD(REG_ITMP3, REG_PV, disp);
2427 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2429 switch (iptr->opc) {
2432 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2440 M_RETURN(REG_RA_CALLEE); /* implicit window restore */
2446 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2451 tptr = (void **) iptr->target;
2453 s4ptr = iptr->val.a;
2454 l = s4ptr[1]; /* low */
2455 i = s4ptr[2]; /* high */
2457 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2459 M_INTMOVE(s1, REG_ITMP1);
2461 else if (l <= 4095) {
2462 M_ADD_IMM(s1, -l, REG_ITMP1);
2465 ICONST(REG_ITMP2, l);
2466 /* XXX: do I need to truncate s1 to 32-bit ? */
2467 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2475 M_CMP_IMM(REG_ITMP1, i);
2478 ICONST(REG_ITMP2, i);
2479 M_CMP(REG_ITMP1, REG_ITMP2);
2482 codegen_addreference(cd, (basicblock *) tptr[0]);
2483 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2485 /* build jump table top down and use address of lowest entry */
2487 /* s4ptr += 3 + i; */
2491 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
2492 dseg_addtarget(cd, (basicblock *) tptr[0]);
2497 /* length of dataseg after last dseg_addtarget is used by load */
2499 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2500 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2501 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2506 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2508 s4 i, /*l, */val, *s4ptr;
2511 tptr = (void **) iptr->target;
2513 s4ptr = iptr->val.a;
2514 /*l = s4ptr[0];*/ /* default */
2515 i = s4ptr[1]; /* count */
2517 MCODECHECK((i<<2)+8);
2518 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2524 if ((val >= -4096) && (val <= 4095)) {
2527 ICONST(REG_ITMP2, val);
2528 M_CMP(s1, REG_ITMP2);
2531 codegen_addreference(cd, (basicblock *) tptr[0]);
2536 tptr = (void **) iptr->target;
2537 codegen_addreference(cd, (basicblock *) tptr[0]);
2544 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2545 /* op1 = arg count val.a = builtintable entry */
2551 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2552 /* op1 = arg count, val.a = method pointer */
2554 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2555 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2556 case ICMD_INVOKEINTERFACE:
2558 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2559 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
2563 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
2564 md = lm->parseddesc;
2568 s3 = md->paramcount;
2570 MCODECHECK((s3 << 1) + 64);
2572 /* copy arguments to registers or stack location */
2574 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
2575 if (src->varkind == ARGVAR)
2577 if (IS_INT_LNG_TYPE(src->type)) {
2578 if (!md->params[s3].inmemory) {
2579 s1 = rd->argintregs[md->params[s3].regoff];
2580 d = emit_load_s1(jd, iptr, src, s1);
2583 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
2584 M_STX(d, REG_SP, md->params[s3].regoff * 8);
2588 if (!md->params[s3].inmemory) {
2589 s1 = rd->argfltregs[md->params[s3].regoff];
2590 d = emit_load_s1(jd, iptr, src, s1);
2591 if (IS_2_WORD_TYPE(src->type))
2597 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
2598 if (IS_2_WORD_TYPE(src->type))
2599 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2601 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2606 switch (iptr->opc) {
2608 disp = dseg_addaddress(cd, bte->fp);
2609 d = md->returntype.type;
2611 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2612 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2614 /* XXX: how do builtins handle the register window? */
2615 /* disp = (s4) (cd->mcodeptr - cd->mcodebase);*/
2616 /* M_LDA(REG_PV, REG_RA, -disp);*/
2618 /* if op1 == true, we need to check for an exception */
2620 if (iptr->op1 == true) {
2621 M_BEQZ(REG_RESULT_CALLER, 0);
2622 codegen_add_fillinstacktrace_ref(cd);
2627 case ICMD_INVOKESPECIAL:
2628 M_BEQZ(rd->argintregs[0], 0);
2629 codegen_add_nullpointerexception_ref(cd);
2633 case ICMD_INVOKESTATIC:
2635 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2637 disp = dseg_addaddress(cd, NULL);
2639 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2642 if (opt_showdisassemble) {
2646 d = um->methodref->parseddesc.md->returntype.type;
2649 disp = dseg_addaddress(cd, lm->stubroutine);
2650 d = lm->parseddesc->returntype.type;
2653 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in callee pv */
2654 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2656 /* XXX no need to restore PV, when its in the regs */
2659 case ICMD_INVOKEVIRTUAL:
2660 gen_nullptr_check(rd->argintregs[0]);
2663 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2665 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2667 if (opt_showdisassemble) {
2672 d = um->methodref->parseddesc.md->returntype.type;
2675 s1 = OFFSET(vftbl_t, table[0]) +
2676 sizeof(methodptr) * lm->vftblindex;
2677 d = lm->parseddesc->returntype.type;
2680 M_ALD(REG_METHODPTR, rd->argintregs[0],
2681 OFFSET(java_objectheader, vftbl));
2682 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2683 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2685 /* XXX no need to restore PV, when its in the regs */
2688 case ICMD_INVOKEINTERFACE:
2689 gen_nullptr_check(rd->argintregs[0]);
2692 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
2694 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2696 if (opt_showdisassemble) {
2702 d = um->methodref->parseddesc.md->returntype.type;
2705 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2706 sizeof(methodptr*) * lm->class->index;
2708 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2710 d = lm->parseddesc->returntype.type;
2713 M_ALD(REG_METHODPTR, rd->argintregs[0],
2714 OFFSET(java_objectheader, vftbl));
2715 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2716 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2717 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2719 /* XXX no need to restore PV, when its in the regs */
2723 /* d contains return type */
2725 if (d != TYPE_VOID) {
2726 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
2727 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT_CALLER);
2728 M_INTMOVE(REG_RESULT_CALLER, s1);
2730 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
2731 if (IS_2_WORD_TYPE(iptr->dst->type)) {
2732 M_DBLMOVE(REG_FRESULT, s1);
2734 M_FLTMOVE(REG_FRESULT, s1);
2737 emit_store(jd, iptr, iptr->dst, s1);
2742 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2743 /* op1: 0 == array, 1 == class */
2744 /* val.a: (classinfo*) superclass */
2746 /* superclass is an interface:
2748 * OK if ((sub == NULL) ||
2749 * (sub->vftbl->interfacetablelength > super->index) &&
2750 * (sub->vftbl->interfacetable[-super->index] != NULL));
2752 * superclass is a class:
2754 * OK if ((sub == NULL) || (0
2755 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2756 * super->vftbl->diffvall));
2759 if (iptr->op1 == 1) {
2761 vftbl_t *supervftbl;
2764 super = (classinfo *) iptr->val.a;
2766 if (super == NULL) {
2771 superindex = super->index;
2772 supervftbl = super->vftbl;
2775 #if defined(ENABLE_THREADS)
2776 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2779 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2781 /* calculate interface checkcast code size */
2785 s2 += (opt_showdisassemble ? 2 : 0);
2787 /* calculate class checkcast code size */
2789 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2791 s3 += (opt_showdisassemble ? 2 : 0);
2793 /* if class is not resolved, check which code to call */
2795 if (super == NULL) {
2796 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2799 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2801 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2802 (constant_classref *) iptr->target,
2805 if (opt_showdisassemble) {
2809 M_ILD(REG_ITMP2, REG_PV, disp);
2810 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2811 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2815 /* interface checkcast code */
2817 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2818 if (super == NULL) {
2819 codegen_addpatchref(cd,
2820 PATCHER_checkcast_instanceof_interface,
2821 (constant_classref *) iptr->target,
2824 if (opt_showdisassemble) {
2833 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2834 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2835 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2836 M_BLEZ(REG_ITMP3, 0);
2837 codegen_add_classcastexception_ref(cd, s1);
2839 M_ALD(REG_ITMP3, REG_ITMP2,
2840 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2841 superindex * sizeof(methodptr*)));
2842 M_BEQZ(REG_ITMP3, 0);
2843 codegen_add_classcastexception_ref(cd, s1);
2846 if (super == NULL) {
2852 /* class checkcast code */
2854 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2855 if (super == NULL) {
2856 disp = dseg_add_unique_address(cd, NULL);
2858 codegen_addpatchref(cd,
2859 PATCHER_checkcast_instanceof_class,
2860 (constant_classref *) iptr->target,
2863 if (opt_showdisassemble) {
2868 disp = dseg_add_address(cd, supervftbl);
2874 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2875 M_ALD(REG_ITMP3, REG_PV, disp);
2876 #if defined(ENABLE_THREADS)
2877 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2879 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2880 /* if (s1 != REG_ITMP1) { */
2881 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2882 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2883 /* #if defined(ENABLE_THREADS) */
2884 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2886 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2889 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2890 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2891 M_ALD(REG_ITMP3, REG_PV, disp);
2892 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2893 #if defined(ENABLE_THREADS)
2894 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2897 M_CMP(REG_ITMP3, REG_ITMP2);
2898 M_BULT(0); /* branch if ITMP3 < ITMP2 */
2899 codegen_add_classcastexception_ref(cd, s1);
2903 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
2906 /* array type cast-check */
2908 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
2909 M_INTMOVE(s1, rd->argintregs[0]);
2911 disp = dseg_addaddress(cd, iptr->val.a);
2913 if (iptr->val.a == NULL) {
2914 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2915 (constant_classref *) iptr->target,
2918 if (opt_showdisassemble) {
2923 M_ALD(rd->argintregs[1], REG_PV, disp);
2924 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
2925 M_ALD(REG_ITMP3, REG_PV, disp);
2926 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2929 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2930 M_BEQZ(REG_RESULT_CALLER, 0);
2931 codegen_add_classcastexception_ref(cd, s1);
2934 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
2938 emit_store(jd, iptr, iptr->dst, d);
2944 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2949 } /* for instruction */
2951 /* copy values to interface registers */
2953 src = bptr->outstack;
2954 len = bptr->outdepth;
2956 #if defined(ENABLE_LSRA)
2961 if ((src->varkind != STACKVAR)) {
2963 if (IS_FLT_DBL_TYPE(s2)) {
2964 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
2965 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2966 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
2969 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
2973 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2974 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2975 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
2978 M_STX(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
2984 } /* if (bptr -> flags >= BBREACHED) */
2985 } /* for basic block */
2987 dseg_createlinenumbertable(cd);
2989 /* generate stubs */
2991 emit_exception_stubs(jd);
2992 emit_patcher_stubs(jd);
2993 emit_replacement_stubs(jd);
2997 /* everything's ok */
3006 /* createcompilerstub **********************************************************
3008 Creates a stub routine which calls the compiler.
3010 *******************************************************************************/
3012 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3013 #define COMPILERSTUB_CODESIZE 4 * 4
3015 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3018 u1 *createcompilerstub(methodinfo *m)
3020 u1 *s; /* memory to hold the stub */
3026 s = CNEW(u1, COMPILERSTUB_SIZE);
3028 /* set data pointer and code pointer */
3031 s = s + COMPILERSTUB_DATASIZE;
3033 /* mark start of dump memory area */
3035 dumpsize = dump_size();
3037 cd = DNEW(codegendata);
3040 /* Store the codeinfo pointer in the same place as in the
3041 methodheader for compiled methods. */
3043 code = code_codeinfo_new(m);
3045 d[0] = (ptrint) asm_call_jit_compiler;
3047 d[2] = (ptrint) code;
3049 /* code for the stub */
3050 /* no window save yet, user caller's PV */
3051 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3052 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3053 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
3056 #if defined(ENABLE_STATISTICS)
3058 count_cstub_len += COMPILERSTUB_SIZE;
3061 /* release dump area */
3063 dump_release(dumpsize);
3070 /* createnativestub ************************************************************
3072 Creates a stub routine which calls a native method.
3074 *******************************************************************************/
3076 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3078 /* fabort("help me!"); */
3079 printf("createnativestub not implemented\n");
3084 * These are local overrides for various environment variables in Emacs.
3085 * Please do not remove this and leave it at the end of the file, where
3086 * Emacs will automagically detect them.
3087 * ---------------------------------------------------------------------
3090 * indent-tabs-mode: t
3094 * vim:noexpandtab:sw=4:ts=4: