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
31 Changes: Edwin Steiner
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-common.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;
102 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
103 unresolved_method *um;
104 builtintable_entry *bte;
106 rplpoint *replacementpoint;
110 /* get required compiler data */
117 /* prevent compiler warnings */
128 #if 0 /* no leaf optimization yet */
129 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
131 savedregs_num = 16; /* register-window save area */
134 /* space to save used callee saved registers */
136 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
137 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
139 cd->stackframesize = rd->memuse + savedregs_num;
141 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
142 if (checksync && (m->flags & ACC_SYNCHRONIZED))
143 cd->stackframesize++;
146 /* create method header */
148 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
149 (void) dseg_adds4(cd, cd->stackframesize * 8); /* FrameSize */
151 #if defined(ENABLE_THREADS)
152 /* IsSync contains the offset relative to the stack pointer for the
153 argument of monitor_exit used in the exception handler. Since the
154 offset could be zero and give a wrong meaning of the flag it is
158 if (checksync && (m->flags & ACC_SYNCHRONIZED))
159 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
162 (void) dseg_adds4(cd, 0); /* IsSync */
164 (void) dseg_adds4(cd, jd->isleafmethod); /* IsLeaf */
165 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
166 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
168 dseg_addlinenumbertablesize(cd);
170 (void) dseg_adds4(cd, jd->exceptiontablelength); /* ExTableSize */
172 /* create exception table */
174 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
175 dseg_addtarget(cd, ex->start);
176 dseg_addtarget(cd, ex->end);
177 dseg_addtarget(cd, ex->handler);
178 (void) dseg_addaddress(cd, ex->catchtype.any);
181 /* save register window and create stack frame (if necessary) */
183 if (cd->stackframesize)
184 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
186 /* save return address and used callee saved registers */
188 p = cd->stackframesize;
189 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
190 p--; M_DST(rd->savfltregs[i], REG_SP, (WINSAVE_REGS + p) * 8);
193 /* take arguments out of register or stack frame */
197 for (p = 0, l = 0; p < md->paramcount; p++) {
198 t = md->paramtypes[p].type;
200 varindex = jd->local_map[l * 5 + t];
203 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
206 if (varindex == UNUSED)
211 s1 = md->params[p].regoff;
212 if (IS_INT_LNG_TYPE(t)) { /* integer args */
213 if (!md->params[p].inmemory) { /* register arguments */
214 s2 = rd->argintregs[s1];
215 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
216 M_INTMOVE(s2, var->vv.regoff);
218 } else { /* reg arg -> spilled */
219 M_STX(s2, REG_SP, (WINSAVE_REGS + var->vv.regoff) * 8);
222 } else { /* stack arguments */
223 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
224 M_LDX(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
226 } else { /* stack arg -> spilled */
227 var->vv.regoff = cd->stackframesize + s1;
231 } else { /* floating args */
232 if (!md->params[p].inmemory) { /* register arguments */
233 s2 = rd->argfltregs[s1];
234 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
235 M_FLTMOVE(s2, var->vv.regoff);
237 } else { /* reg arg -> spilled */
238 M_DST(s2, REG_SP, (WINSAVE_REGS + var->vv.regoff) * 8);
241 } else { /* stack arguments */
242 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
243 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
245 } else { /* stack-arg -> spilled */
246 var->vv.regoff = cd->stackframesize + s1;
253 /* XXX monitor enter and tracing */
257 /* end of header generation */
259 replacementpoint = jd->code->rplpoints;
261 /* walk through all basic blocks */
263 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
265 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
267 if (bptr->flags >= BBREACHED) {
269 /* branch resolving */
273 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
274 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
275 brefs->branchpos, bptr->mpc);
279 /* handle replacement points */
281 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
282 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
287 /* copy interface registers to their destination */
292 #if defined(ENABLE_LSRA)
296 src = bptr->invars[len];
297 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
298 /* d = reg_of_var(m, src, REG_ITMP1); */
299 if (!(src->flags & INMEMORY))
303 M_INTMOVE(REG_ITMP1, d);
304 emit_store(jd, NULL, src, d);
311 var = VAR(bptr->invars[len]);
312 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
313 d = codegen_reg_of_var(0, var, REG_ITMP1);
314 M_INTMOVE(REG_ITMP1, d);
315 emit_store(jd, NULL, var, d);
318 assert((var->flags & INOUT));
321 #if defined(ENABLE_LSRA)
324 /* walk through all instructions */
328 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
329 if (iptr->line != currentline) {
330 dseg_addlinenumber(cd, iptr->line);
331 currentline = iptr->line;
334 MCODECHECK(64); /* an instruction usually needs < 64 words */
337 case ICMD_INLINE_START:
338 case ICMD_INLINE_END:
341 case ICMD_NOP: /* ... ==> ... */
344 /* constant operations ************************************************/
346 case ICMD_ICONST: /* ... ==> ..., constant */
348 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
349 ICONST(d, iptr->sx.val.i);
350 emit_store_dst(jd, iptr, d);
353 case ICMD_LCONST: /* ... ==> ..., constant */
355 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
356 LCONST(d, iptr->sx.val.l);
357 emit_store_dst(jd, iptr, d);
360 case ICMD_FCONST: /* ... ==> ..., constant */
362 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
363 disp = dseg_addfloat(cd, iptr->sx.val.f);
364 M_FLD(d, REG_PV, disp);
365 emit_store_dst(jd, iptr, d);
368 case ICMD_DCONST: /* ... ==> ..., constant */
370 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
371 disp = dseg_adddouble(cd, iptr->sx.val.d);
372 M_DLD(d, REG_PV, disp);
373 emit_store_dst(jd, iptr, d);
376 case ICMD_ACONST: /* ... ==> ..., constant */
378 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
380 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
381 disp = dseg_addaddress(cd, NULL);
383 codegen_addpatchref(cd, PATCHER_aconst,
387 if (opt_showdisassemble) {
391 M_ALD(d, REG_PV, disp);
394 if (iptr->sx.val.anyptr == NULL) {
395 M_INTMOVE(REG_ZERO, d);
397 disp = dseg_addaddress(cd, iptr->sx.val.anyptr);
398 M_ALD(d, REG_PV, disp);
401 emit_store_dst(jd, iptr, d);
405 /* load/store/copy/move operations ************************************/
407 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
408 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
409 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
410 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
411 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
412 case ICMD_ISTORE: /* ..., value ==> ... */
413 case ICMD_LSTORE: /* ..., value ==> ... */
414 case ICMD_ASTORE: /* ..., value ==> ... */
415 case ICMD_FSTORE: /* ..., value ==> ... */
416 case ICMD_DSTORE: /* ..., value ==> ... */
420 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
424 /* pop/dup/swap operations ********************************************/
426 /* attention: double and longs are only one entry in CACAO ICMDs */
428 case ICMD_POP: /* ..., value ==> ... */
429 case ICMD_POP2: /* ..., value, value ==> ... */
433 /* integer operations *************************************************/
435 case ICMD_INEG: /* ..., value ==> ..., - value */
438 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
439 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
440 M_SUB(REG_ZERO, s1, d);
441 emit_store_dst(jd, iptr, d);
444 case ICMD_I2L: /* ..., value ==> ..., value */
446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
449 emit_store_dst(jd, iptr, d);
452 case ICMD_L2I: /* ..., value ==> ..., value */
454 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
455 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
456 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
457 emit_store_dst(jd, iptr, d);
460 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
463 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
464 M_SLLX_IMM(s1, 56, d);
465 M_SRAX_IMM( d, 56, d);
466 emit_store_dst(jd, iptr, d);
469 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
473 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
474 M_SLLX_IMM(s1, 48, d);
475 M_SRAX_IMM( d, 48, d);
476 emit_store_dst(jd, iptr, d);
479 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
482 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
483 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
484 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
486 emit_store_dst(jd, iptr, d);
490 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
491 /* sx.val.i = constant */
493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
494 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
495 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
496 M_ADD_IMM(s1, iptr->sx.val.i, d);
498 ICONST(REG_ITMP2, iptr->sx.val.i);
499 M_ADD(s1, REG_ITMP2, d);
501 emit_store_dst(jd, iptr, d);
504 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
505 /* sx.val.l = constant */
507 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
509 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
510 M_ADD_IMM(s1, iptr->sx.val.l, d);
512 LCONST(REG_ITMP2, iptr->sx.val.l);
513 M_ADD(s1, REG_ITMP2, d);
515 emit_store_dst(jd, iptr, d);
518 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
522 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
523 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
525 emit_store_dst(jd, iptr, d);
528 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
529 /* sx.val.i = constant */
531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
533 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
534 M_SUB_IMM(s1, iptr->sx.val.i, d);
536 ICONST(REG_ITMP2, iptr->sx.val.i);
537 M_SUB(s1, REG_ITMP2, d);
539 emit_store_dst(jd, iptr, d);
542 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
543 /* sx.val.l = constant */
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
547 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
548 M_SUB_IMM(s1, iptr->sx.val.l, d);
550 LCONST(REG_ITMP2, iptr->sx.val.l);
551 M_SUB(s1, REG_ITMP2, d);
553 emit_store_dst(jd, iptr, d);
556 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
560 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
563 emit_store_dst(jd, iptr, d);
566 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
567 /* sx.val.i = constant */
569 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
570 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
571 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
572 M_MULX_IMM(s1, iptr->sx.val.i, d);
574 ICONST(REG_ITMP2, iptr->sx.val.i);
575 M_MULX(s1, REG_ITMP2, d);
577 emit_store_dst(jd, iptr, d);
580 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
581 /* sx.val.l = constant */
583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
585 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
586 M_MULX_IMM(s1, iptr->sx.val.l, d);
588 LCONST(REG_ITMP2, iptr->sx.val.l);
589 M_MULX(s1, REG_ITMP2, d);
591 emit_store_dst(jd, iptr, d);
594 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
595 /* XXX could also clear Y and use 32bit div */
596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
601 /* XXX trim s2 like s1 ? */
603 emit_store_dst(jd, iptr, d);
606 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
608 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
609 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
613 emit_store_dst(jd, iptr, d);
616 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
619 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
620 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
623 /* XXX trim s2 like s1 ? */
627 emit_store_dst(jd, iptr, d);
630 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
634 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
639 emit_store_dst(jd, iptr, d);
642 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
643 case ICMD_LDIVPOW2: /* val.i = constant */
645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
647 M_SRAX_IMM(s1, 63, REG_ITMP2);
648 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
649 M_ADD(s1, REG_ITMP2, REG_ITMP2);
650 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
651 emit_store_dst(jd, iptr, d);
654 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
657 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
658 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 emit_store_dst(jd, iptr, d);
664 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
665 case ICMD_LSHLCONST: /* val.i = constant */
667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
669 M_SLLX_IMM(s1, iptr->sx.val.i, d);
670 emit_store_dst(jd, iptr, d);
673 case ICMD_ISHR: /* ..., 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_ISHRCONST: /* ..., 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 M_SRA_IMM(s1, iptr->sx.val.i, d);
688 emit_store_dst(jd, iptr, d);
691 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
695 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
697 emit_store_dst(jd, iptr, d);
700 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
701 /* sx.val.i = constant */
703 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
705 M_SRL_IMM(s1, iptr->sx.val.i, d);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
715 emit_store_dst(jd, iptr, d);
718 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
719 /* sx.val.i = constant */
721 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
722 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
723 M_SRAX_IMM(s1, iptr->sx.val.i, d);
724 emit_store_dst(jd, iptr, d);
727 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
729 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
730 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
733 emit_store_dst(jd, iptr, d);
736 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
737 /* sx.val.i = constant */
739 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
741 M_SRLX_IMM(s1, iptr->sx.val.i, d);
742 emit_store_dst(jd, iptr, d);
745 case ICMD_IAND: /* ..., 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_ITMP2);
752 emit_store_dst(jd, iptr, d);
755 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
756 /* sx.val.i = constant */
758 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
760 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
761 M_AND_IMM(s1, iptr->sx.val.i, d);
763 ICONST(REG_ITMP2, iptr->sx.val.i);
764 M_AND(s1, REG_ITMP2, d);
766 emit_store_dst(jd, iptr, d);
769 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
770 /* sx.val.i = constant */
772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
774 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
776 M_MOV(s1, REG_ITMP1);
779 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
780 M_AND_IMM(s1, iptr->sx.val.i, d);
783 M_SUB(REG_ZERO, s1, d);
784 M_AND_IMM(d, iptr->sx.val.i, d);
786 ICONST(REG_ITMP2, iptr->sx.val.i);
787 M_AND(s1, REG_ITMP2, d);
790 M_SUB(REG_ZERO, s1, d);
791 M_AND(d, REG_ITMP2, d);
793 M_SUB(REG_ZERO, d, d);
794 emit_store_dst(jd, iptr, d);
797 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
798 /* sx.val.l = constant */
800 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
801 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
803 M_AND_IMM(s1, iptr->sx.val.l, d);
805 LCONST(REG_ITMP2, iptr->sx.val.l);
806 M_AND(s1, REG_ITMP2, d);
808 emit_store_dst(jd, iptr, d);
811 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
812 /* sx.val.l = constant */
814 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
815 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
817 M_MOV(s1, REG_ITMP1);
820 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
821 M_AND_IMM(s1, iptr->sx.val.l, d);
824 M_SUB(REG_ZERO, s1, d);
825 M_AND_IMM(d, iptr->sx.val.l, d);
827 LCONST(REG_ITMP2, iptr->sx.val.l);
828 M_AND(s1, REG_ITMP2, d);
831 M_SUB(REG_ZERO, s1, d);
832 M_AND(d, REG_ITMP2, d);
834 M_SUB(REG_ZERO, d, d);
835 emit_store_dst(jd, iptr, d);
838 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
841 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
842 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
843 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
845 emit_store_dst(jd, iptr, d);
848 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
849 /* sx.val.i = constant */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
853 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
854 M_OR_IMM(s1, iptr->sx.val.i, d);
856 ICONST(REG_ITMP2, iptr->sx.val.i);
857 M_OR(s1, REG_ITMP2, d);
859 emit_store_dst(jd, iptr, d);
862 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
863 /* sx.val.l = constant */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
867 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
868 M_OR_IMM(s1, iptr->sx.val.l, d);
870 LCONST(REG_ITMP2, iptr->sx.val.l);
871 M_OR(s1, REG_ITMP2, d);
873 emit_store_dst(jd, iptr, d);
876 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
880 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
881 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
883 emit_store_dst(jd, iptr, d);
886 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
887 /* sx.val.i = constant */
889 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
890 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
891 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
892 M_XOR_IMM(s1, iptr->sx.val.i, d);
894 ICONST(REG_ITMP2, iptr->sx.val.i);
895 M_XOR(s1, REG_ITMP2, d);
897 emit_store_dst(jd, iptr, d);
900 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
901 /* sx.val.l = constant */
903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
904 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
905 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
906 M_XOR_IMM(s1, iptr->sx.val.l, d);
908 LCONST(REG_ITMP2, iptr->sx.val.l);
909 M_XOR(s1, REG_ITMP2, d);
911 emit_store_dst(jd, iptr, d);
915 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
918 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
922 M_XCMOVLT_IMM(-1, d);
924 emit_store_dst(jd, iptr, d);
928 /* floating operations ************************************************/
930 case ICMD_FNEG: /* ..., value ==> ..., - value */
932 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
933 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
935 emit_store_dst(jd, iptr, d);
938 case ICMD_DNEG: /* ..., value ==> ..., - value */
940 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
941 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
943 emit_store_dst(jd, iptr, d);
946 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
948 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
949 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
950 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
952 emit_store_dst(jd, iptr, d);
955 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
957 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
958 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
959 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
961 emit_store_dst(jd, iptr, d);
964 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
966 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
967 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
968 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
970 emit_store_dst(jd, iptr, d);
973 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
975 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
976 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
977 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
979 emit_store_dst(jd, iptr, d);
982 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
984 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
985 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
986 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
988 emit_store_dst(jd, iptr, d);
991 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
993 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
994 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
995 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
997 emit_store_dst(jd, iptr, d);
1000 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1002 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1003 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1004 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1006 emit_store_dst(jd, iptr, d);
1009 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1011 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1012 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1013 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1015 emit_store_dst(jd, iptr, d);
1019 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1020 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1021 disp = dseg_addfloat(cd, 0.0);
1022 M_IST (s1, REG_PV_CALLEE, disp);
1023 M_FLD (d, REG_PV_CALLEE, disp);
1024 M_CVTIF (d, d); /* rd gets translated to double target register */
1025 emit_store_dst(jd, iptr, d);
1029 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1030 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1031 disp = dseg_adddouble(cd, 0.0);
1032 M_STX (s1, REG_PV_CALLEE, disp);
1033 M_DLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1034 M_CVTLF (REG_FTMP2, d); /* rd gets translated to double target register */
1035 emit_store_dst(jd, iptr, d);
1038 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1039 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1041 disp = dseg_addfloat(cd, 0.0);
1042 M_CVTFI(s1, REG_FTMP2);
1043 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1044 M_ILD(d, REG_PV, disp);
1045 emit_store_dst(jd, iptr, d);
1049 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1050 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1052 disp = dseg_addfloat(cd, 0.0);
1053 M_CVTDI(s1, REG_FTMP2);
1054 M_FST(REG_FTMP2, REG_PV, disp);
1055 M_ILD(d, REG_PV, disp);
1056 emit_store_dst(jd, iptr, d);
1059 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1060 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1061 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1062 disp = dseg_adddouble(cd, 0.0);
1063 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1064 M_DST(REG_FTMP2, REG_PV, disp);
1065 M_LDX(d, REG_PV, disp);
1066 emit_store_dst(jd, iptr, d);
1069 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1070 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1071 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1072 disp = dseg_adddouble(cd, 0.0);
1073 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1074 M_DST(REG_FTMP2, REG_PV, disp);
1075 M_LDX(d, REG_PV, disp);
1076 emit_store_dst(jd, iptr, d);
1079 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1081 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1082 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1084 emit_store_dst(jd, iptr, d);
1087 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1089 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1090 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1092 emit_store_dst(jd, iptr, d);
1095 /* XXX merge F/D versions? only compare instr. is different */
1096 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1098 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1099 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1100 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1102 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1103 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1104 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1105 emit_store_dst(jd, iptr, d);
1108 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1110 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1111 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1112 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1114 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1115 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1116 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1117 emit_store_dst(jd, iptr, d);
1120 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1122 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1123 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1126 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1127 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1128 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1129 emit_store_dst(jd, iptr, d);
1132 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1134 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1135 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1136 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1138 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1139 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1140 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1141 emit_store_dst(jd, iptr, d);
1145 /* memory operations **************************************************/
1147 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1149 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1150 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1151 gen_nullptr_check(s1);
1152 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1159 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1160 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1161 if (INSTRUCTION_MUST_CHECK(iptr)) {
1162 gen_nullptr_check(s1);
1165 M_AADD(s2, s1, REG_ITMP3);
1166 M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1167 emit_store_dst(jd, iptr, d);
1170 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1173 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1174 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1175 if (INSTRUCTION_MUST_CHECK(iptr)) {
1176 gen_nullptr_check(s1);
1179 M_AADD(s2, s1, REG_ITMP3);
1180 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1181 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1182 emit_store_dst(jd, iptr, d);
1185 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1187 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1188 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1189 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1190 if (INSTRUCTION_MUST_CHECK(iptr)) {
1191 gen_nullptr_check(s1);
1194 M_AADD(s2, s1, REG_ITMP3);
1195 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1196 M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1197 emit_store_dst(jd, iptr, d);
1200 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1203 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1204 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1205 if (INSTRUCTION_MUST_CHECK(iptr)) {
1206 gen_nullptr_check(s1);
1209 M_ASLL_IMM(s2, 2, REG_ITMP3);
1210 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1211 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1217 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1218 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1219 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1220 if (INSTRUCTION_MUST_CHECK(iptr)) {
1221 gen_nullptr_check(s1);
1224 M_ASLL_IMM(s2, 3, REG_ITMP3);
1225 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1226 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1227 emit_store_dst(jd, iptr, d);
1230 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1232 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1234 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1235 if (INSTRUCTION_MUST_CHECK(iptr)) {
1236 gen_nullptr_check(s1);
1239 M_ASLL_IMM(s2, 2, REG_ITMP3);
1240 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1241 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1242 emit_store_dst(jd, iptr, d);
1245 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1248 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1250 if (INSTRUCTION_MUST_CHECK(iptr)) {
1251 gen_nullptr_check(s1);
1254 M_ASLL_IMM(s2, 3, REG_ITMP3);
1255 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1256 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1257 emit_store_dst(jd, iptr, d);
1260 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1264 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1265 if (INSTRUCTION_MUST_CHECK(iptr)) {
1266 gen_nullptr_check(s1);
1269 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1270 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1271 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1272 emit_store_dst(jd, iptr, d);
1276 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1279 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1280 if (INSTRUCTION_MUST_CHECK(iptr)) {
1281 gen_nullptr_check(s1);
1284 M_AADD(s2, s1, REG_ITMP1);
1285 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1286 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1289 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1290 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1292 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1293 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1294 if (INSTRUCTION_MUST_CHECK(iptr)) {
1295 gen_nullptr_check(s1);
1298 M_AADD(s2, s1, REG_ITMP1);
1299 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1300 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1301 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1304 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1306 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1307 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1308 if (INSTRUCTION_MUST_CHECK(iptr)) {
1309 gen_nullptr_check(s1);
1312 M_ASLL_IMM(s2, 2, REG_ITMP2);
1313 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1314 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1315 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1318 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1321 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1322 if (INSTRUCTION_MUST_CHECK(iptr)) {
1323 gen_nullptr_check(s1);
1326 M_ASLL_IMM(s2, 3, REG_ITMP2);
1327 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1328 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1329 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1332 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1334 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1335 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1336 if (INSTRUCTION_MUST_CHECK(iptr)) {
1337 gen_nullptr_check(s1);
1340 M_ASLL_IMM(s2, 2, REG_ITMP2);
1341 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1342 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1343 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1346 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1348 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1349 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1350 if (INSTRUCTION_MUST_CHECK(iptr)) {
1351 gen_nullptr_check(s1);
1354 M_ASLL_IMM(s2, 3, REG_ITMP2);
1355 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1356 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1357 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1361 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1364 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1365 if (INSTRUCTION_MUST_CHECK(iptr)) {
1366 gen_nullptr_check(s1);
1369 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1371 M_MOV(s1, rd->argintregs[0]);
1372 M_MOV(s3, rd->argintregs[1]);
1373 disp = dseg_addaddress(cd, BUILTIN_canstore);
1374 M_ALD(REG_ITMP3, REG_PV, disp);
1375 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1378 M_BEQZ(REG_RESULT_CALLER, 0);
1379 codegen_add_arraystoreexception_ref(cd);
1382 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1383 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1384 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1385 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1386 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1387 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1391 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1393 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1394 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1395 if (INSTRUCTION_MUST_CHECK(iptr)) {
1396 gen_nullptr_check(s1);
1399 M_AADD(s2, s1, REG_ITMP1);
1400 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1403 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1404 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1406 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1407 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1408 if (INSTRUCTION_MUST_CHECK(iptr)) {
1409 gen_nullptr_check(s1);
1412 M_AADD(s2, s1, REG_ITMP1);
1413 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1414 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1417 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1419 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1420 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1421 if (INSTRUCTION_MUST_CHECK(iptr)) {
1422 gen_nullptr_check(s1);
1425 M_ASLL_IMM(s2, 2, REG_ITMP2);
1426 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1427 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1430 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1434 if (INSTRUCTION_MUST_CHECK(iptr)) {
1435 gen_nullptr_check(s1);
1438 M_ASLL_IMM(s2, 3, REG_ITMP2);
1439 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1440 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1443 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1446 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1447 if (INSTRUCTION_MUST_CHECK(iptr)) {
1448 gen_nullptr_check(s1);
1451 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1452 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1453 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1457 case ICMD_GETSTATIC: /* ... ==> ..., value */
1459 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1460 unresolved_field *uf = iptr->sx.s23.s3.uf;
1462 fieldtype = uf->fieldref->parseddesc.fd->type;
1464 disp = dseg_addaddress(cd, NULL);
1466 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
1468 if (opt_showdisassemble) {
1473 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1475 disp = dseg_addaddress(cd, &(fi->value));
1477 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1478 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1480 if (opt_showdisassemble) {
1486 M_ALD(REG_ITMP1, REG_PV, disp);
1487 switch (fieldtype) {
1489 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1490 M_ILD_INTERN(d, REG_ITMP1, 0);
1491 emit_store_dst(jd, iptr, d);
1494 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1495 M_LDX_INTERN(d, REG_ITMP1, 0);
1496 emit_store_dst(jd, iptr, d);
1499 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1500 M_ALD_INTERN(d, REG_ITMP1, 0);
1501 emit_store_dst(jd, iptr, d);
1504 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1505 M_FLD_INTERN(d, REG_ITMP1, 0);
1506 emit_store_dst(jd, iptr, d);
1509 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1510 M_DLD_INTERN(d, REG_ITMP1, 0);
1511 emit_store_dst(jd, iptr, d);
1516 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1518 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1519 unresolved_field *uf = iptr->sx.s23.s3.uf;
1521 fieldtype = uf->fieldref->parseddesc.fd->type;
1523 disp = dseg_addaddress(cd, NULL);
1525 codegen_addpatchref(cd, PATCHER_get_putstatic,
1526 iptr->sx.s23.s3.uf, disp);
1528 if (opt_showdisassemble) {
1533 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1535 disp = dseg_addaddress(cd, &(fi->value));
1537 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1538 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1540 if (opt_showdisassemble) {
1546 M_ALD(REG_ITMP1, REG_PV, disp);
1547 switch (fieldtype) {
1549 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1550 M_IST_INTERN(s2, REG_ITMP1, 0);
1553 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1554 M_STX_INTERN(s2, REG_ITMP1, 0);
1557 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1558 M_AST_INTERN(s2, REG_ITMP1, 0);
1561 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1562 M_FST_INTERN(s2, REG_ITMP1, 0);
1565 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1566 M_DST_INTERN(s2, REG_ITMP1, 0);
1571 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1572 /* val = value (in current instruction) */
1573 /* following NOP) */
1575 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1576 unresolved_field *uf = iptr->sx.s23.s3.uf;
1578 fieldtype = uf->fieldref->parseddesc.fd->type;
1580 disp = dseg_addaddress(cd, NULL);
1582 codegen_addpatchref(cd, PATCHER_get_putstatic,
1585 if (opt_showdisassemble) {
1590 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1592 fieldtype = fi->type;
1595 disp = dseg_addaddress(cd, &(fi->value));
1597 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1598 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1600 if (opt_showdisassemble) {
1606 M_ALD(REG_ITMP1, REG_PV, disp);
1607 switch (fieldtype) {
1609 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1612 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1615 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1618 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1621 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1627 case ICMD_GETFIELD: /* ... ==> ..., value */
1629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1630 gen_nullptr_check(s1);
1632 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1633 unresolved_field *uf = iptr->sx.s23.s3.uf;
1635 fieldtype = uf->fieldref->parseddesc.fd->type;
1637 codegen_addpatchref(cd, PATCHER_get_putfield,
1638 iptr->sx.s23.s3.uf, 0);
1640 if (opt_showdisassemble) {
1647 disp = iptr->sx.s23.s3.fmiref->p.field->offset;
1650 switch (fieldtype) {
1652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1654 emit_store_dst(jd, iptr, d);
1657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1659 emit_store_dst(jd, iptr, d);
1662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1664 emit_store_dst(jd, iptr, d);
1667 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1669 emit_store_dst(jd, iptr, d);
1672 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1674 emit_store_dst(jd, iptr, d);
1679 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1681 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1682 gen_nullptr_check(s1);
1684 /*if (!IS_FLT_DBL_TYPE(fieldtype)) {
1685 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1687 s2 = emit_load_s2(jd, iptr, REG_IFTMP);
1690 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1691 unresolved_field *uf = iptr->sx.s23.s3.uf;
1693 fieldtype = uf->fieldref->parseddesc.fd->type;
1695 codegen_addpatchref(cd, PATCHER_get_putfield,
1696 iptr->sx.s23.s3.uf, 0);
1698 if (opt_showdisassemble) {
1705 disp = iptr->sx.s23.s3.fmiref->p.field->offset;
1708 switch (fieldtype) {
1710 M_IST(s2, s1, disp);
1713 M_STX(s2, s1, disp);
1716 M_AST(s2, s1, disp);
1719 M_FST(s2, s1, disp);
1722 M_DST(s2, s1, disp);
1727 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1728 /* val = value (in current instruction) */
1729 /* following NOP) */
1731 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1732 gen_nullptr_check(s1);
1734 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1735 unresolved_field *uf = iptr->sx.s23.s3.uf;
1737 fieldtype = uf->fieldref->parseddesc.fd->type;
1739 codegen_addpatchref(cd, PATCHER_get_putfield,
1742 if (opt_showdisassemble) {
1750 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1752 fieldtype = fi->type;
1758 switch (fieldtype) {
1760 M_IST(REG_ZERO, s1, disp);
1763 M_STX(REG_ZERO, s1, disp);
1766 M_AST(REG_ZERO, s1, disp);
1769 M_FST(REG_ZERO, s1, disp);
1772 M_DST(REG_ZERO, s1, disp);
1778 /* branch operations **************************************************/
1780 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1783 M_INTMOVE(s1, REG_ITMP2_XPTR);
1785 #ifdef ENABLE_VERIFIER
1786 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1787 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1788 iptr->sx.s23.s2.uc, 0);
1790 if (opt_showdisassemble)
1793 #endif /* ENABLE_VERIFIER */
1795 disp = dseg_addaddress(cd, asm_handle_exception);
1796 M_ALD(REG_ITMP2, REG_PV, disp);
1797 M_JMP(REG_ITMP3_XPC, REG_ITMP2, REG_ZERO);
1799 M_NOP; /* nop ensures that XPC is less than the end */
1800 /* of basic block */
1804 case ICMD_GOTO: /* ... ==> ... */
1805 case ICMD_RET: /* ... ==> ... */
1808 codegen_addreference(cd, iptr->dst.block);
1813 case ICMD_JSR: /* ... ==> ... */
1816 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
1821 case ICMD_IFNULL: /* ..., value ==> ... */
1823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1825 codegen_addreference(cd, iptr->dst.block);
1829 case ICMD_IFNONNULL: /* ..., value ==> ... */
1831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1833 codegen_addreference(cd, iptr->dst.block);
1837 case ICMD_IFEQ: /* ..., value ==> ... */
1839 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1840 if (iptr->sx.val.i == 0) {
1843 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1844 M_CMP_IMM(s1, iptr->sx.val.i);
1847 ICONST(REG_ITMP2, iptr->sx.val.i);
1848 M_CMP(s1, REG_ITMP2);
1852 codegen_addreference(cd, iptr->dst.block);
1856 case ICMD_IFLT: /* ..., value ==> ... */
1858 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1859 if (iptr->sx.val.i == 0) {
1862 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1863 M_CMP_IMM(s1, iptr->sx.val.i);
1865 ICONST(REG_ITMP2, iptr->sx.val.i);
1866 M_CMP(s1, REG_ITMP2);
1870 codegen_addreference(cd, iptr->dst.block);
1874 case ICMD_IFLE: /* ..., value ==> ... */
1876 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1877 if (iptr->sx.val.i == 0) {
1881 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1882 M_CMP_IMM(s1, iptr->sx.val.i);
1885 ICONST(REG_ITMP2, iptr->sx.val.i);
1886 M_CMP(s1, REG_ITMP2);
1890 codegen_addreference(cd, iptr->dst.block);
1894 case ICMD_IFNE: /* ..., value ==> ... */
1896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1897 if (iptr->sx.val.i == 0) {
1901 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1902 M_CMP_IMM(s1, iptr->sx.val.i);
1905 ICONST(REG_ITMP2, iptr->sx.val.i);
1906 M_CMP(s1, REG_ITMP2);
1910 codegen_addreference(cd, iptr->dst.block);
1914 case ICMD_IFGT: /* ..., value ==> ... */
1916 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1917 if (iptr->sx.val.i == 0) {
1920 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1921 M_CMP_IMM(s1, iptr->sx.val.i);
1923 ICONST(REG_ITMP2, iptr->sx.val.i);
1924 M_CMP(s1, REG_ITMP2);
1928 codegen_addreference(cd, iptr->dst.block);
1932 case ICMD_IFGE: /* ..., value ==> ... */
1934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1935 if (iptr->sx.val.i == 0) {
1939 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1940 M_CMP_IMM(s1, iptr->sx.val.i);
1943 ICONST(REG_ITMP2, iptr->sx.val.i);
1944 M_CMP(s1, REG_ITMP2);
1948 codegen_addreference(cd, iptr->dst.block);
1952 case ICMD_IF_LEQ: /* ..., value ==> ... */
1954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1955 if (iptr->sx.val.l == 0) {
1959 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1960 M_CMP_IMM(s1, iptr->sx.val.l);
1963 LCONST(REG_ITMP2, iptr->sx.val.l);
1964 M_CMP(s1, REG_ITMP2);
1968 codegen_addreference(cd, iptr->dst.block);
1972 case ICMD_IF_LLT: /* ..., value ==> ... */
1974 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1975 if (iptr->sx.val.l == 0) {
1978 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1979 M_CMP_IMM(s1, iptr->sx.val.l);
1981 ICONST(REG_ITMP2, iptr->sx.val.l);
1982 M_CMP(s1, REG_ITMP2);
1986 codegen_addreference(cd, iptr->dst.block);
1990 case ICMD_IF_LLE: /* ..., value ==> ... */
1992 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1993 if (iptr->sx.val.l == 0) {
1997 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1998 M_CMP_IMM(s1, iptr->sx.val.l);
2001 ICONST(REG_ITMP2, iptr->sx.val.l);
2002 M_CMP(s1, REG_ITMP2);
2006 codegen_addreference(cd, iptr->dst.block);
2010 case ICMD_IF_LNE: /* ..., value ==> ... */
2012 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2013 if (iptr->sx.val.l == 0) {
2017 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2018 M_CMP_IMM(s1, iptr->sx.val.i);
2021 ICONST(REG_ITMP2, iptr->sx.val.l);
2022 M_CMP(s1, REG_ITMP2);
2026 codegen_addreference(cd, iptr->dst.block);
2030 case ICMD_IF_LGT: /* ..., value ==> ... */
2032 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2033 if (iptr->sx.val.l == 0) {
2036 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2037 M_CMP_IMM(s1, iptr->sx.val.l);
2039 ICONST(REG_ITMP2, iptr->sx.val.l);
2040 M_CMP(s1, REG_ITMP2);
2044 codegen_addreference(cd, iptr->dst.block);
2048 case ICMD_IF_LGE: /* ..., value ==> ... */
2050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2051 if (iptr->sx.val.l == 0) {
2055 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2056 M_CMP_IMM(s1, iptr->sx.val.l);
2059 ICONST(REG_ITMP2, iptr->sx.val.l);
2060 M_CMP(s1, REG_ITMP2);
2064 codegen_addreference(cd, iptr->dst.block);
2069 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2070 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2073 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2076 codegen_addreference(cd, iptr->dst.block);
2080 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2082 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2083 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2086 codegen_addreference(cd, iptr->dst.block);
2090 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2091 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2094 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2097 codegen_addreference(cd, iptr->dst.block);
2101 case ICMD_IF_ICMPNE: /* 32-bit compare */
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2104 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2107 codegen_addreference(cd, iptr->dst.block);
2111 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2113 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2114 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2117 codegen_addreference(cd, iptr->dst.block);
2121 case ICMD_IF_ICMPLT: /* 32-bit compare */
2123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2127 codegen_addreference(cd, iptr->dst.block);
2131 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2134 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2137 codegen_addreference(cd, iptr->dst.block);
2141 case ICMD_IF_ICMPGT: /* 32-bit compare */
2143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2144 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2147 codegen_addreference(cd, iptr->dst.block);
2151 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2154 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2157 codegen_addreference(cd, iptr->dst.block);
2161 case ICMD_IF_ICMPLE: /* 32-bit compare */
2163 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2164 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2167 codegen_addreference(cd, iptr->dst.block);
2172 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2174 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2175 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2178 codegen_addreference(cd, iptr->dst.block);
2182 case ICMD_IF_ICMPGE: /* 32-bit compare */
2184 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2185 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2188 codegen_addreference(cd, iptr->dst.block);
2193 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2196 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2197 M_INTMOVE(s1, REG_RESULT_CALLEE);
2198 goto nowperformreturn;
2200 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2202 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2203 M_INTMOVE(s1, REG_RESULT_CALLEE);
2205 #ifdef ENABLE_VERIFIER
2206 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2207 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2208 iptr->sx.s23.s2.uc, 0);
2210 if (opt_showdisassemble)
2213 #endif /* ENABLE_VERIFIER */
2214 goto nowperformreturn;
2216 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2219 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2220 M_FLTMOVE(s1, REG_FRESULT);
2221 goto nowperformreturn;
2223 case ICMD_RETURN: /* ... ==> ... */
2229 p = cd->stackframesize;
2231 #if !defined(NDEBUG)
2232 if (opt_verbosecall) {
2233 M_LDA(REG_SP, REG_SP, -3 * 8);
2234 M_AST(REG_RA_CALLEE, REG_SP, 0 * 8); /* XXX: no need to save anything but FRES ? */
2235 /* M_STX(REG_RESULT, REG_SP, 1 * 8); */
2236 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2238 disp = dseg_addaddress(cd, m);
2239 M_ALD(rd->argintregs[0], REG_PV, disp);
2240 M_MOV(REG_RESULT_CALLEE, rd->argintregs[1]);
2241 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2242 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2244 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2245 M_ALD(REG_ITMP3, REG_PV, disp);
2246 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2249 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2250 /* M_LDX(REG_RESULT, REG_SP, 1 * 8); */
2251 M_ALD(REG_RA_CALLEE, REG_SP, 0 * 8);
2252 M_LDA(REG_SP, REG_SP, 3 * 8);
2256 #if defined(ENABLE_THREADS)
2257 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2258 /* XXX: REG_RESULT is save, but what about FRESULT? */
2259 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2261 switch (iptr->opc) {
2264 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2268 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2269 M_ALD(REG_ITMP3, REG_PV, disp);
2270 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2272 switch (iptr->opc) {
2275 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2283 M_RETURN(REG_RA_CALLEE); /* implicit window restore */
2289 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2292 branch_target_t *table;
2294 table = iptr->dst.table;
2296 l = iptr->sx.s23.s2.tablelow;
2297 i = iptr->sx.s23.s3.tablehigh;
2299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2301 M_INTMOVE(s1, REG_ITMP1);
2303 else if (l <= 4095) {
2304 M_ADD_IMM(s1, -l, REG_ITMP1);
2307 ICONST(REG_ITMP2, l);
2308 /* XXX: do I need to truncate s1 to 32-bit ? */
2309 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2317 M_CMP_IMM(REG_ITMP1, i);
2320 ICONST(REG_ITMP2, i);
2321 M_CMP(REG_ITMP1, REG_ITMP2);
2324 codegen_addreference(cd, table[0].block); /* default target */
2325 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2327 /* build jump table top down and use address of lowest entry */
2332 dseg_add_target(cd, table->block);
2337 /* length of dataseg after last dseg_addtarget is used by load */
2339 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2340 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2341 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2346 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2349 lookup_target_t *lookup;
2351 lookup = iptr->dst.lookup;
2353 i = iptr->sx.s23.s2.lookupcount;
2355 MCODECHECK((i<<2)+8);
2356 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2359 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2360 M_CMP_IMM(s1, lookup->value);
2362 ICONST(REG_ITMP2, lookup->value);
2363 M_CMP(s1, REG_ITMP2);
2366 codegen_addreference(cd, lookup->target.block);
2372 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2379 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2381 bte = iptr->sx.s23.s3.bte;
2385 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2387 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2388 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2389 case ICMD_INVOKEINTERFACE:
2391 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2393 um = iptr->sx.s23.s3.um;
2394 md = um->methodref->parseddesc.md;
2397 lm = iptr->sx.s23.s3.fmiref->p.method;
2399 md = lm->parseddesc;
2403 s3 = md->paramcount;
2405 MCODECHECK((s3 << 1) + 64);
2407 /* copy arguments to registers or stack location */
2409 for (s3 = s3 - 1; s3 >= 0; s3--) {
2410 var = VAR(iptr->sx.s23.s2.args[s3]);
2412 if (var->flags & PREALLOC)
2415 if (IS_INT_LNG_TYPE(var->type)) {
2416 if (!md->params[s3].inmemory) {
2417 s1 = rd->argintregs[md->params[s3].regoff];
2418 d = emit_load(jd, iptr, var, s1);
2422 d = emit_load(jd, iptr, var, REG_ITMP1);
2423 M_STX(d, REG_SP, md->params[s3].regoff * 8);
2427 if (!md->params[s3].inmemory) {
2428 s1 = rd->argfltregs[md->params[s3].regoff];
2429 d = emit_load(jd, iptr, var, s1);
2430 if (IS_2_WORD_TYPE(var->type))
2436 d = emit_load(jd, iptr, var, REG_FTMP1);
2437 if (IS_2_WORD_TYPE(var->type))
2438 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2440 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2445 switch (iptr->opc) {
2447 /* XXX needs manual attention! */
2448 disp = dseg_addaddress(cd, bte->fp);
2449 d = md->returntype.type;
2451 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
2452 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2454 /* XXX: how do builtins handle the register window? */
2455 /* disp = (s4) (cd->mcodeptr - cd->mcodebase);*/
2456 /* M_LDA(REG_PV, REG_RA, -disp);*/
2459 if (INSTRUCTION_MUST_CHECK(iptr)) {
2460 M_BEQZ(REG_RESULT_CALLER, 0);
2461 codegen_add_fillinstacktrace_ref(cd);
2466 case ICMD_INVOKESPECIAL:
2468 codegen_add_nullpointerexception_ref(cd);
2472 case ICMD_INVOKESTATIC:
2473 /* XXX needs manual attention! */
2475 disp = dseg_addaddress(cd, NULL);
2477 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2480 if (opt_showdisassemble) {
2485 disp = dseg_addaddress(cd, lm->stubroutine);
2487 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in callee pv */
2488 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2490 /* XXX no need to restore PV, when its in the regs */
2493 case ICMD_INVOKEVIRTUAL:
2494 gen_nullptr_check(REG_A0);
2497 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2499 if (opt_showdisassemble) {
2506 s1 = OFFSET(vftbl_t, table[0]) +
2507 sizeof(methodptr) * lm->vftblindex;
2509 M_ALD(REG_METHODPTR, REG_A0,
2510 OFFSET(java_objectheader, vftbl));
2511 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2512 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2514 /* XXX no need to restore PV, when its in the regs */
2517 case ICMD_INVOKEINTERFACE:
2518 /* XXX needs manual attention! */
2519 gen_nullptr_check(rd->argintregs[0]);
2522 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2524 if (opt_showdisassemble) {
2532 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2533 sizeof(methodptr*) * lm->class->index;
2535 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2538 M_ALD(REG_METHODPTR, REG_A0,
2539 OFFSET(java_objectheader, vftbl));
2540 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2541 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2542 M_JMP(REG_RA_CALLER, REG_PV_CALLER, REG_ZERO);
2544 /* XXX no need to restore PV, when its in the regs */
2548 /* d contains return type */
2550 if (d != TYPE_VOID) {
2551 if (IS_INT_LNG_TYPE(d)) {
2552 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2553 M_INTMOVE(REG_RESULT_CALLER, s1);
2556 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2557 if (IS_2_WORD_TYPE(d)) {
2558 M_DBLMOVE(REG_FRESULT, s1);
2560 M_FLTMOVE(REG_FRESULT, s1);
2563 emit_store_dst(jd, iptr, s1);
2568 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2569 /* XXX needs manual attention! */
2570 /* val.a: (classinfo*) superclass */
2572 /* superclass is an interface:
2574 * OK if ((sub == NULL) ||
2575 * (sub->vftbl->interfacetablelength > super->index) &&
2576 * (sub->vftbl->interfacetable[-super->index] != NULL));
2578 * superclass is a class:
2580 * OK if ((sub == NULL) || (0
2581 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2582 * super->vftbl->diffvall));
2585 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2587 vftbl_t *supervftbl;
2590 super = iptr->sx.s23.s3.c.cls;
2592 if (super == NULL) {
2597 superindex = super->index;
2598 supervftbl = super->vftbl;
2601 #if defined(ENABLE_THREADS)
2602 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2607 /* calculate interface checkcast code size */
2611 s2 += (opt_showdisassemble ? 2 : 0);
2613 /* calculate class checkcast code size */
2615 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2617 s3 += (opt_showdisassemble ? 2 : 0);
2619 /* if class is not resolved, check which code to call */
2621 if (super == NULL) {
2622 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2625 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2627 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2628 iptr->sx.s23.s3.c.ref,
2631 if (opt_showdisassemble) {
2635 M_ILD(REG_ITMP2, REG_PV, disp);
2636 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2637 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2641 /* interface checkcast code */
2643 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2644 if (super == NULL) {
2645 codegen_addpatchref(cd,
2646 PATCHER_checkcast_instanceof_interface,
2647 iptr->sx.s23.s3.c.ref,
2650 if (opt_showdisassemble) {
2659 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2660 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2661 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2662 M_BLEZ(REG_ITMP3, 0);
2663 codegen_add_classcastexception_ref(cd, s1);
2665 M_ALD(REG_ITMP3, REG_ITMP2,
2666 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2667 superindex * sizeof(methodptr*)));
2668 M_BEQZ(REG_ITMP3, 0);
2669 codegen_add_classcastexception_ref(cd, s1);
2672 if (super == NULL) {
2678 /* class checkcast code */
2680 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2681 if (super == NULL) {
2682 disp = dseg_add_unique_address(cd, NULL);
2684 codegen_addpatchref(cd,
2685 PATCHER_checkcast_instanceof_class,
2686 iptr->sx.s23.s3.c.ref,
2689 if (opt_showdisassemble) {
2694 disp = dseg_add_address(cd, supervftbl);
2700 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2701 M_ALD(REG_ITMP3, REG_PV, disp);
2702 #if defined(ENABLE_THREADS)
2703 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2705 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2706 /* if (s1 != REG_ITMP1) { */
2707 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2708 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2709 /* #if defined(ENABLE_THREADS) */
2710 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2712 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2715 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2716 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2717 M_ALD(REG_ITMP3, REG_PV, disp);
2718 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2719 #if defined(ENABLE_THREADS)
2720 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2723 M_CMP(REG_ITMP3, REG_ITMP2);
2724 M_BULT(0); /* branch if ITMP3 < ITMP2 */
2725 codegen_add_classcastexception_ref(cd, s1);
2729 d = codegen_reg_of_dst(jd, iptr, s1);
2732 /* array type cast-check */
2734 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
2735 M_INTMOVE(s1, rd->argintregs[0]);
2737 disp = dseg_addaddress(cd, iptr->sx.s23.s3.c.cls);
2739 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2740 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2741 iptr->sx.s23.s3.c.ref,
2744 if (opt_showdisassemble) {
2749 M_ALD(rd->argintregs[1], REG_PV, disp);
2750 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
2751 M_ALD(REG_ITMP3, REG_PV, disp);
2752 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2755 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2756 M_BEQZ(REG_RESULT_CALLER, 0);
2757 codegen_add_classcastexception_ref(cd, s1);
2760 d = codegen_reg_of_dst(jd, iptr, s1);
2764 emit_store_dst(jd, iptr, d);
2770 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2775 } /* for instruction */
2779 } /* if (bptr -> flags >= BBREACHED) */
2780 } /* for basic block */
2782 dseg_createlinenumbertable(cd);
2784 /* generate exception and patcher stubs */
2786 emit_exception_stubs(jd);
2787 emit_patcher_stubs(jd);
2788 emit_replacement_stubs(jd);
2792 /* everything's ok */
2801 /* createcompilerstub **********************************************************
2803 Creates a stub routine which calls the compiler.
2805 *******************************************************************************/
2807 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
2808 #define COMPILERSTUB_CODESIZE 4 * 4
2810 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2813 u1 *createcompilerstub(methodinfo *m)
2815 u1 *s; /* memory to hold the stub */
2821 s = CNEW(u1, COMPILERSTUB_SIZE);
2823 /* set data pointer and code pointer */
2826 s = s + COMPILERSTUB_DATASIZE;
2828 /* mark start of dump memory area */
2830 dumpsize = dump_size();
2832 cd = DNEW(codegendata);
2835 /* Store the codeinfo pointer in the same place as in the
2836 methodheader for compiled methods. */
2838 code = code_codeinfo_new(m);
2840 d[0] = (ptrint) asm_call_jit_compiler;
2842 d[2] = (ptrint) code;
2844 /* code for the stub */
2845 /* no window save yet, user caller's PV */
2846 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2847 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2848 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2851 #if defined(ENABLE_STATISTICS)
2853 count_cstub_len += COMPILERSTUB_SIZE;
2856 /* release dump area */
2858 dump_release(dumpsize);
2865 /* createnativestub ************************************************************
2867 Creates a stub routine which calls a native method.
2869 *******************************************************************************/
2871 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2873 /* fabort("help me!"); */
2874 printf("createnativestub not implemented\n");
2879 * These are local overrides for various environment variables in Emacs.
2880 * Please do not remove this and leave it at the end of the file, where
2881 * Emacs will automagically detect them.
2882 * ---------------------------------------------------------------------
2885 * indent-tabs-mode: t
2889 * vim:noexpandtab:sw=4:ts=4: