1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
3 Copyright (C) 1996-2005, 2006, 2007 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 $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
40 /* #include "vm/jit/sparc64/arch.h" */
41 #include "vm/jit/sparc64/codegen.h"
43 #include "mm/memory.h"
45 #include "native/jni.h"
46 #include "native/native.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
49 #include "vm/global.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/codegen-common.h"
53 #include "vm/jit/dseg.h"
54 #include "vm/jit/emit-common.h"
55 #include "vm/jit/jit.h"
56 #include "vm/jit/parse.h"
57 #include "vm/jit/patcher.h"
58 #include "vm/jit/reg.h"
59 #include "vm/jit/replace.h"
60 #include "vm/jit/stacktrace.h"
61 #include "vmcore/loader.h"
62 #include "vmcore/options.h"
64 /* XXX use something like this for window control ?
65 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
67 #define REG_PV REG_PV_CALLEE
71 /* printf("fits disp %d?\n", disp); */
73 return (disp >= -4096) && (disp <= 4095);
76 /* codegen *********************************************************************
78 Generates machine code.
80 *******************************************************************************/
82 bool codegen(jitdata *jd)
88 s4 len, s1, s2, s3, d, disp;
94 constant_classref *cr;
95 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
96 unresolved_method *um;
97 builtintable_entry *bte;
100 unresolved_field *uf;
104 /* get required compiler data */
111 /* prevent compiler warnings */
120 s4 savedregs_num, localbase;
122 #if 0 /* no leaf optimization yet */
123 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
125 savedregs_num = WINSAVE_CNT + ABIPARAMS_CNT; /* register-window save area */
128 /* space to save used callee saved registers */
130 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
131 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
133 cd->stackframesize = rd->memuse + savedregs_num;
135 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
136 if (checksync && (m->flags & ACC_SYNCHRONIZED))
137 cd->stackframesize++;
140 /* keep stack 16-byte aligned (ABI requirement) */
142 if (cd->stackframesize & 1)
143 cd->stackframesize++;
145 /* create method header */
147 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
148 (void) dseg_add_unique_s4(cd, 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_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
161 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
163 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
164 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
165 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
166 dseg_addlinenumbertablesize(cd);
167 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
169 /* create exception table */
171 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
172 dseg_add_target(cd, ex->start);
173 dseg_add_target(cd, ex->end);
174 dseg_add_target(cd, ex->handler);
175 (void) dseg_add_unique_address(cd, ex->catchtype.any);
178 /* save register window and create stack frame (if necessary) */
180 if (cd->stackframesize)
181 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
184 /* save callee saved float registers (none right now) */
186 p = cd->stackframesize;
187 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
188 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
193 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
194 emit_verbosecall_enter(jd);
199 /* take arguments out of register or stack frame */
203 /* when storing locals, use this as base */
204 localbase = JITSTACK;
206 /* since the register allocator does not know about the shifting window
207 * arg regs need to be copied via the stack
209 if (md->argintreguse > 0) {
210 /* allocate scratch space for copying in to save(i&l) regs */
211 M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
213 localbase += INT_ARG_CNT * 8;
215 /* XXX could use the param slots on the stack for this! */
216 for (p = 0; p < INT_ARG_CNT; p++)
217 M_STX(REG_WINDOW_TRANSPOSE(rd->argintregs[p]), REG_SP, JITSTACK + (p * 8));
221 for (p = 0, l = 0; p < md->paramcount; p++) {
222 t = md->paramtypes[p].type;
224 varindex = jd->local_map[l * 5 + t];
227 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
230 if (varindex == UNUSED)
235 s1 = md->params[p].regoff;
236 if (IS_INT_LNG_TYPE(t)) { /* integer args */
237 if (!md->params[p].inmemory) { /* register arguments */
238 /*s2 = rd->argintregs[s1];*/
239 /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
240 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
241 /*M_INTMOVE(s2, var->vv.regoff);*/
242 M_LDX(var->vv.regoff, REG_SP, JITSTACK + (s1 * 8));
244 } else { /* reg arg -> spilled */
245 /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
247 M_LDX(REG_ITMP1, REG_SP, JITSTACK + (s1 * 8));
248 M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
251 } else { /* stack arguments */
252 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
253 M_LDX(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
255 } else { /* stack arg -> spilled */
256 /* add the callers window save registers */
257 var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
261 } else { /* floating args */
262 if (!md->params[p].inmemory) { /* register arguments */
263 s2 = rd->argfltregs[s1];
264 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
265 M_FLTMOVE(s2, var->vv.regoff);
267 } else { /* reg arg -> spilled */
268 M_DST(s2, REG_SP, localbase + (var->vv.regoff) * 8);
271 } else { /* stack arguments */
272 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
273 M_DLD(var->vv.regoff, REG_FP, JITSTACK + (s1 * 8));
275 } else { /* stack-arg -> spilled */
276 var->vv.regoff = cd->stackframesize + JITSTACK_CNT + s1;
282 if (md->argintreguse > 0) {
283 /* release scratch space */
284 M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
288 /* XXX monitor enter */
295 /* end of header generation */
297 /* create replacement points */
299 REPLACEMENT_POINTS_INIT(cd, jd);
301 /* walk through all basic blocks */
303 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
305 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
307 if (bptr->flags >= BBREACHED) {
309 /* branch resolving */
311 codegen_resolve_branchrefs(cd, bptr);
313 /* handle replacement points */
316 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
317 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
323 /* copy interface registers to their destination */
328 #if defined(ENABLE_LSRA)
329 #error XXX LSRA not tested yet
333 src = bptr->invars[len];
334 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
335 /* d = reg_of_var(m, src, REG_ITMP1); */
336 if (!(src->flags & INMEMORY))
340 M_INTMOVE(REG_ITMP1, d);
341 emit_store(jd, NULL, src, d);
348 var = VAR(bptr->invars[len]);
349 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
350 d = codegen_reg_of_var(0, var, REG_ITMP1);
351 M_INTMOVE(REG_ITMP2_XPTR, d);
352 emit_store(jd, NULL, var, d);
355 assert((var->flags & INOUT));
358 #if defined(ENABLE_LSRA)
361 /* walk through all instructions */
365 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
366 if (iptr->line != currentline) {
367 dseg_addlinenumber(cd, iptr->line);
368 currentline = iptr->line;
371 MCODECHECK(64); /* an instruction usually needs < 64 words */
375 case ICMD_INLINE_START:
376 case ICMD_INLINE_END:
379 case ICMD_NOP: /* ... ==> ... */
382 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
385 emit_nullpointer_check(cd, iptr, s1);
388 /* constant operations ************************************************/
390 case ICMD_ICONST: /* ... ==> ..., constant */
392 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
393 ICONST(d, iptr->sx.val.i);
394 emit_store_dst(jd, iptr, d);
397 case ICMD_LCONST: /* ... ==> ..., constant */
399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
400 LCONST(d, iptr->sx.val.l);
401 emit_store_dst(jd, iptr, d);
404 case ICMD_FCONST: /* ... ==> ..., constant */
406 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
407 disp = dseg_add_float(cd, iptr->sx.val.f);
408 M_FLD(d, REG_PV, disp);
409 emit_store_dst(jd, iptr, d);
412 case ICMD_DCONST: /* ... ==> ..., constant */
414 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
415 disp = dseg_add_double(cd, iptr->sx.val.d);
416 M_DLD(d, REG_PV, disp);
417 emit_store_dst(jd, iptr, d);
420 case ICMD_ACONST: /* ... ==> ..., constant */
422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
424 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
425 cr = iptr->sx.val.c.ref;
426 disp = dseg_add_unique_address(cd, cr);
428 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
430 M_ALD(d, REG_PV, disp);
434 if (iptr->sx.val.anyptr == NULL) {
435 M_INTMOVE(REG_ZERO, d);
438 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
439 M_ALD(d, REG_PV, disp);
442 emit_store_dst(jd, iptr, d);
446 /* load/store/copy/move operations ************************************/
448 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
449 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
450 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
451 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
452 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
453 case ICMD_ISTORE: /* ..., value ==> ... */
454 case ICMD_LSTORE: /* ..., value ==> ... */
455 case ICMD_FSTORE: /* ..., value ==> ... */
456 case ICMD_DSTORE: /* ..., value ==> ... */
460 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
464 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
465 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
469 /* pop/dup/swap operations ********************************************/
471 /* attention: double and longs are only one entry in CACAO ICMDs */
473 case ICMD_POP: /* ..., value ==> ... */
474 case ICMD_POP2: /* ..., value, value ==> ... */
478 /* integer operations *************************************************/
480 case ICMD_INEG: /* ..., value ==> ..., - value */
483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
484 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
485 M_SUB(REG_ZERO, s1, d);
486 emit_store_dst(jd, iptr, d);
489 case ICMD_I2L: /* ..., value ==> ..., value */
491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
492 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
494 emit_store_dst(jd, iptr, d);
497 case ICMD_L2I: /* ..., value ==> ..., value */
499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
500 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
501 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
502 emit_store_dst(jd, iptr, d);
505 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
507 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
509 M_SLLX_IMM(s1, 56, d);
510 M_SRAX_IMM( d, 56, d);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
516 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
518 M_SLLX_IMM(s1, 48, d);
519 M_SRLX_IMM( d, 48, d);
520 emit_store_dst(jd, iptr, d);
523 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
525 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
526 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
527 M_SLLX_IMM(s1, 48, d);
528 M_SRAX_IMM( d, 48, d);
529 emit_store_dst(jd, iptr, d);
532 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
536 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
537 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
539 emit_store_dst(jd, iptr, d);
543 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
544 /* sx.val.i = constant */
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
548 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
549 M_ADD_IMM(s1, iptr->sx.val.i, d);
551 ICONST(REG_ITMP2, iptr->sx.val.i);
552 M_ADD(s1, REG_ITMP2, d);
554 emit_store_dst(jd, iptr, d);
557 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
558 /* sx.val.l = constant */
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
562 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
563 M_ADD_IMM(s1, iptr->sx.val.l, d);
565 LCONST(REG_ITMP2, iptr->sx.val.l);
566 M_ADD(s1, REG_ITMP2, d);
568 emit_store_dst(jd, iptr, d);
571 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
575 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
576 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 emit_store_dst(jd, iptr, d);
581 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
582 /* sx.val.i = constant */
584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
587 M_SUB_IMM(s1, iptr->sx.val.i, d);
589 ICONST(REG_ITMP2, iptr->sx.val.i);
590 M_SUB(s1, REG_ITMP2, d);
592 emit_store_dst(jd, iptr, d);
595 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
596 /* sx.val.l = constant */
598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
599 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
600 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
601 M_SUB_IMM(s1, iptr->sx.val.l, d);
603 LCONST(REG_ITMP2, iptr->sx.val.l);
604 M_SUB(s1, REG_ITMP2, d);
606 emit_store_dst(jd, iptr, d);
609 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
612 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
613 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
616 emit_store_dst(jd, iptr, d);
619 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
620 /* sx.val.i = constant */
622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
624 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
625 M_MULX_IMM(s1, iptr->sx.val.i, d);
627 ICONST(REG_ITMP2, iptr->sx.val.i);
628 M_MULX(s1, REG_ITMP2, d);
630 emit_store_dst(jd, iptr, d);
633 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
634 /* sx.val.l = constant */
636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
638 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
639 M_MULX_IMM(s1, iptr->sx.val.l, d);
641 LCONST(REG_ITMP2, iptr->sx.val.l);
642 M_MULX(s1, REG_ITMP2, d);
644 emit_store_dst(jd, iptr, d);
647 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
648 /* XXX could also clear Y and use 32bit div */
649 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
650 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
651 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
652 emit_arithmetic_check(cd, iptr, s2);
654 /* XXX trim s2 like s1 ? */
656 emit_store_dst(jd, iptr, d);
659 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664 emit_arithmetic_check(cd, iptr, s2);
666 emit_store_dst(jd, iptr, d);
669 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
674 emit_arithmetic_check(cd, iptr, s2);
676 /* XXX trim s2 like s1 ? */
680 emit_store_dst(jd, iptr, d);
683 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
687 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
688 emit_arithmetic_check(cd, iptr, s2);
692 emit_store_dst(jd, iptr, d);
695 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
696 case ICMD_LDIVPOW2: /* val.i = constant */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700 M_SRAX_IMM(s1, 63, REG_ITMP2);
701 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
702 M_ADD(s1, REG_ITMP2, REG_ITMP2);
703 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
704 emit_store_dst(jd, iptr, d);
707 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
710 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
711 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
712 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
714 emit_store_dst(jd, iptr, d);
717 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
718 case ICMD_LSHLCONST: /* val.i = constant */
720 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
721 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
722 M_SLLX_IMM(s1, iptr->sx.val.i, d);
723 emit_store_dst(jd, iptr, d);
726 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
729 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
730 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
732 emit_store_dst(jd, iptr, d);
735 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
736 /* sx.val.i = constant */
738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
739 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
740 M_SRA_IMM(s1, iptr->sx.val.i, d);
741 emit_store_dst(jd, iptr, d);
744 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
746 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
747 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
748 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
750 emit_store_dst(jd, iptr, d);
753 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
754 /* sx.val.i = constant */
756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
757 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
758 M_SRL_IMM(s1, iptr->sx.val.i, d);
759 emit_store_dst(jd, iptr, d);
762 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
764 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
765 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
766 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
768 emit_store_dst(jd, iptr, d);
771 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
772 /* sx.val.i = constant */
774 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
776 M_SRAX_IMM(s1, iptr->sx.val.i, d);
777 emit_store_dst(jd, iptr, d);
780 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
782 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
783 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
786 emit_store_dst(jd, iptr, d);
789 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
790 /* sx.val.i = constant */
792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
794 M_SRLX_IMM(s1, iptr->sx.val.i, d);
795 emit_store_dst(jd, iptr, d);
798 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
801 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
802 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
803 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805 emit_store_dst(jd, iptr, d);
808 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
809 /* sx.val.i = constant */
811 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
812 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
813 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
814 M_AND_IMM(s1, iptr->sx.val.i, d);
816 ICONST(REG_ITMP2, iptr->sx.val.i);
817 M_AND(s1, REG_ITMP2, d);
819 emit_store_dst(jd, iptr, d);
822 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
823 /* sx.val.i = constant */
825 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
826 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
829 M_MOV(s1, REG_ITMP1);
832 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
833 M_AND_IMM(s1, iptr->sx.val.i, d);
836 M_SUB(REG_ZERO, s1, d);
837 M_AND_IMM(d, iptr->sx.val.i, d);
839 ICONST(REG_ITMP2, iptr->sx.val.i);
840 M_AND(s1, REG_ITMP2, d);
843 M_SUB(REG_ZERO, s1, d);
844 M_AND(d, REG_ITMP2, d);
846 M_SUB(REG_ZERO, d, d);
847 emit_store_dst(jd, iptr, d);
850 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
851 /* sx.val.l = constant */
853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
856 M_AND_IMM(s1, iptr->sx.val.l, d);
858 LCONST(REG_ITMP2, iptr->sx.val.l);
859 M_AND(s1, REG_ITMP2, d);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
865 /* sx.val.l = constant */
867 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
870 M_MOV(s1, REG_ITMP1);
873 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
874 M_AND_IMM(s1, iptr->sx.val.l, d);
877 M_SUB(REG_ZERO, s1, d);
878 M_AND_IMM(d, iptr->sx.val.l, d);
880 LCONST(REG_ITMP2, iptr->sx.val.l);
881 M_AND(s1, REG_ITMP2, d);
884 M_SUB(REG_ZERO, s1, d);
885 M_AND(d, REG_ITMP2, d);
887 M_SUB(REG_ZERO, d, d);
888 emit_store_dst(jd, iptr, d);
891 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
896 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 emit_store_dst(jd, iptr, d);
901 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
902 /* sx.val.i = constant */
904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
906 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
907 M_OR_IMM(s1, iptr->sx.val.i, d);
909 ICONST(REG_ITMP2, iptr->sx.val.i);
910 M_OR(s1, REG_ITMP2, d);
912 emit_store_dst(jd, iptr, d);
915 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
916 /* sx.val.l = constant */
918 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
919 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
920 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
921 M_OR_IMM(s1, iptr->sx.val.l, d);
923 LCONST(REG_ITMP2, iptr->sx.val.l);
924 M_OR(s1, REG_ITMP2, d);
926 emit_store_dst(jd, iptr, d);
929 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
932 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
933 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
934 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
936 emit_store_dst(jd, iptr, d);
939 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
940 /* sx.val.i = constant */
942 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
943 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
944 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
945 M_XOR_IMM(s1, iptr->sx.val.i, d);
947 ICONST(REG_ITMP2, iptr->sx.val.i);
948 M_XOR(s1, REG_ITMP2, d);
950 emit_store_dst(jd, iptr, d);
953 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
954 /* sx.val.l = constant */
956 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
957 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
958 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
959 M_XOR_IMM(s1, iptr->sx.val.l, d);
961 LCONST(REG_ITMP2, iptr->sx.val.l);
962 M_XOR(s1, REG_ITMP2, d);
964 emit_store_dst(jd, iptr, d);
968 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
972 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
975 M_XCMOVLT_IMM(-1, d);
977 emit_store_dst(jd, iptr, d);
981 /* floating operations ************************************************/
983 case ICMD_FNEG: /* ..., value ==> ..., - value */
985 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
986 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
988 emit_store_dst(jd, iptr, d);
991 case ICMD_DNEG: /* ..., value ==> ..., - value */
993 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
994 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
996 emit_store_dst(jd, iptr, d);
999 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1001 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1002 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1003 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1005 emit_store_dst(jd, iptr, d);
1008 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1010 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1011 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1012 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1014 emit_store_dst(jd, iptr, d);
1017 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1019 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1020 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1021 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1023 emit_store_dst(jd, iptr, d);
1026 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1028 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1029 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1030 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1032 emit_store_dst(jd, iptr, d);
1035 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1037 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1038 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1039 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1041 emit_store_dst(jd, iptr, d);
1044 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1046 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1047 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1048 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1050 emit_store_dst(jd, iptr, d);
1053 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1055 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1056 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1057 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1059 emit_store_dst(jd, iptr, d);
1062 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1064 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1065 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1066 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1068 emit_store_dst(jd, iptr, d);
1072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1073 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1074 disp = dseg_add_float(cd, 0.0);
1075 M_IST (s1, REG_PV_CALLEE, disp);
1076 M_FLD (d, REG_PV_CALLEE, disp);
1077 M_CVTIF (d, d); /* rd gets translated to double target register */
1078 emit_store_dst(jd, iptr, d);
1082 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1083 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1084 disp = dseg_add_float(cd, 0.0);
1085 M_IST (s1, REG_PV_CALLEE, disp);
1086 M_FLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1087 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1092 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1093 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1094 disp = dseg_add_float(cd, 0.0);
1095 M_CVTFI(s1, REG_FTMP2);
1096 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1097 M_ILD(d, REG_PV, disp);
1098 emit_store_dst(jd, iptr, d);
1102 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1103 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1104 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1105 disp = dseg_add_float(cd, 0.0);
1106 M_CVTDI(s1, REG_FTMP2);
1107 M_FST(REG_FTMP2, REG_PV, disp);
1108 M_ILD(d, REG_PV, disp);
1109 emit_store_dst(jd, iptr, d);
1112 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1113 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1114 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1115 disp = dseg_add_double(cd, 0.0);
1116 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1117 M_DST(REG_FTMP2, REG_PV, disp);
1118 M_LDX(d, REG_PV, disp);
1119 emit_store_dst(jd, iptr, d);
1122 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1123 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1125 disp = dseg_add_double(cd, 0.0);
1126 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1127 M_DST(REG_FTMP2, REG_PV, disp);
1128 M_LDX(d, REG_PV, disp);
1129 emit_store_dst(jd, iptr, d);
1132 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1134 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1135 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1137 emit_store_dst(jd, iptr, d);
1140 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1142 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1143 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1145 emit_store_dst(jd, iptr, d);
1148 /* XXX merge F/D versions? only compare instr. is different */
1149 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1151 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1152 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1155 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1156 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1157 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1158 emit_store_dst(jd, iptr, d);
1161 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1163 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1164 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1165 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1167 M_OR_IMM(REG_ZERO, -1, d); /* less by default (less or unordered) */
1168 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1169 M_CMOVFGT_IMM(1, d); /* 1 if greater */
1170 emit_store_dst(jd, iptr, d);
1173 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1175 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1176 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1177 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1179 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1180 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1181 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1182 emit_store_dst(jd, iptr, d);
1185 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1187 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1188 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1189 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1191 M_OR_IMM(REG_ZERO, 1, d); /* greater by default (greater or unordered) */
1192 M_CMOVFEQ_IMM(0, d); /* 0 if equal */
1193 M_CMOVFLT_IMM(-1, d); /* -1 if less */
1194 emit_store_dst(jd, iptr, d);
1198 /* memory operations **************************************************/
1200 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1203 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1204 emit_nullpointer_check(cd, iptr, s1);
1205 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1206 emit_store_dst(jd, iptr, d);
1209 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1212 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1213 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1214 emit_array_checks(cd, iptr, s1, s2);
1215 M_AADD(s2, s1, REG_ITMP3);
1216 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1217 emit_store_dst(jd, iptr, d);
1220 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1223 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1224 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1225 emit_array_checks(cd, iptr, s1, s2);
1226 M_AADD(s2, s1, REG_ITMP3);
1227 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1228 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1229 emit_store_dst(jd, iptr, d);
1232 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1234 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1235 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1236 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1237 emit_array_checks(cd, iptr, s1, s2);
1238 M_AADD(s2, s1, REG_ITMP3);
1239 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1240 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1241 emit_store_dst(jd, iptr, d);
1244 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1246 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1247 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1248 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1249 emit_array_checks(cd, iptr, s1, s2);
1250 M_ASLL_IMM(s2, 2, REG_ITMP3);
1251 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1252 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1253 emit_store_dst(jd, iptr, d);
1256 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1258 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1259 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1260 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1261 emit_array_checks(cd, iptr, s1, s2);
1262 M_ASLL_IMM(s2, 3, REG_ITMP3);
1263 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1264 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1270 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1271 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1272 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1273 emit_array_checks(cd, iptr, s1, s2);
1274 M_ASLL_IMM(s2, 2, REG_ITMP3);
1275 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1276 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1277 emit_store_dst(jd, iptr, d);
1280 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1282 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1283 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1284 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1285 emit_array_checks(cd, iptr, s1, s2);
1286 M_ASLL_IMM(s2, 3, REG_ITMP3);
1287 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1288 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1289 emit_store_dst(jd, iptr, d);
1292 case ICMD_AALOAD: /* ..., 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 emit_array_checks(cd, iptr, s1, s2);
1298 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1299 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1300 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1301 emit_store_dst(jd, iptr, d);
1305 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1308 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1309 emit_array_checks(cd, iptr, s1, s2);
1310 M_AADD(s2, s1, REG_ITMP1);
1311 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1312 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1315 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1316 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1318 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1319 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1320 emit_array_checks(cd, iptr, s1, s2);
1321 M_AADD(s2, s1, REG_ITMP1);
1322 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1323 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1324 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1327 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1331 emit_array_checks(cd, iptr, s1, s2);
1332 M_ASLL_IMM(s2, 2, REG_ITMP2);
1333 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1334 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1335 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1338 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1342 emit_array_checks(cd, iptr, s1, s2);
1343 M_ASLL_IMM(s2, 3, REG_ITMP2);
1344 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1345 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1346 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1349 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 emit_array_checks(cd, iptr, s1, s2);
1354 M_ASLL_IMM(s2, 2, REG_ITMP2);
1355 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1356 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1357 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1360 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1362 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1363 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1364 emit_array_checks(cd, iptr, s1, s2);
1365 M_ASLL_IMM(s2, 3, REG_ITMP2);
1366 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1367 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1368 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1372 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1374 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1375 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1376 emit_array_checks(cd, iptr, s1, s2);
1377 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1379 M_MOV(s1, rd->argintregs[0]);
1380 M_MOV(s3, rd->argintregs[1]);
1381 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1382 M_ALD(REG_ITMP3, REG_PV, disp);
1383 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1386 M_BEQZ(REG_RESULT_CALLER, 0);
1387 codegen_add_arraystoreexception_ref(cd);
1390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1391 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1392 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1393 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1394 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1395 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1399 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1402 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1403 emit_array_checks(cd, iptr, s1, s2);
1404 M_AADD(s2, s1, REG_ITMP1);
1405 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1408 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1409 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1412 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1413 emit_array_checks(cd, iptr, s1, s2);
1414 M_AADD(s2, s1, REG_ITMP1);
1415 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1416 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1419 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1421 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1422 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1423 emit_array_checks(cd, iptr, s1, s2);
1424 M_ASLL_IMM(s2, 2, REG_ITMP2);
1425 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1426 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1429 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1431 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1432 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1433 emit_array_checks(cd, iptr, s1, s2);
1434 M_ASLL_IMM(s2, 3, REG_ITMP2);
1435 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1436 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1439 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1442 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1443 emit_array_checks(cd, iptr, s1, s2);
1444 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1445 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1446 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1450 case ICMD_GETSTATIC: /* ... ==> ..., value */
1452 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1453 uf = iptr->sx.s23.s3.uf;
1454 fieldtype = uf->fieldref->parseddesc.fd->type;
1455 disp = dseg_add_unique_address(cd, uf);
1457 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1460 fi = iptr->sx.s23.s3.fmiref->p.field;
1461 fieldtype = fi->type;
1462 disp = dseg_add_address(cd, &(fi->value));
1464 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1465 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1468 M_ALD(REG_ITMP1, REG_PV, disp);
1470 switch (fieldtype) {
1472 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1473 M_ILD_INTERN(d, REG_ITMP1, 0);
1476 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1477 M_LDX_INTERN(d, REG_ITMP1, 0);
1480 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1481 M_ALD_INTERN(d, REG_ITMP1, 0);
1484 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1485 M_FLD_INTERN(d, REG_ITMP1, 0);
1488 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1489 M_DLD_INTERN(d, REG_ITMP1, 0);
1492 emit_store_dst(jd, iptr, d);
1495 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1497 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1498 uf = iptr->sx.s23.s3.uf;
1499 fieldtype = uf->fieldref->parseddesc.fd->type;
1500 disp = dseg_add_unique_address(cd, uf);
1502 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1505 fi = iptr->sx.s23.s3.fmiref->p.field;
1506 fieldtype = fi->type;
1507 disp = dseg_add_address(cd, &(fi->value));
1509 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1510 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1513 M_ALD(REG_ITMP1, REG_PV, disp);
1515 switch (fieldtype) {
1517 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1518 M_IST_INTERN(s1, REG_ITMP1, 0);
1521 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1522 M_STX_INTERN(s1, REG_ITMP1, 0);
1525 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1526 M_AST_INTERN(s1, REG_ITMP1, 0);
1529 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1530 M_FST_INTERN(s1, REG_ITMP1, 0);
1533 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1534 M_DST_INTERN(s1, REG_ITMP1, 0);
1539 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1540 /* val = value (in current instruction) */
1541 /* following NOP) */
1543 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1544 uf = iptr->sx.s23.s3.uf;
1545 fieldtype = uf->fieldref->parseddesc.fd->type;
1546 disp = dseg_add_unique_address(cd, uf);
1548 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1551 fi = iptr->sx.s23.s3.fmiref->p.field;
1552 fieldtype = fi->type;
1553 disp = dseg_add_address(cd, &(fi->value));
1555 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1556 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1559 M_ALD(REG_ITMP1, REG_PV, disp);
1561 switch (fieldtype) {
1563 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1566 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1569 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1572 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1575 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1581 case ICMD_GETFIELD: /* ... ==> ..., value */
1583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1584 emit_nullpointer_check(cd, iptr, s1);
1586 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1587 uf = iptr->sx.s23.s3.uf;
1589 fieldtype = uf->fieldref->parseddesc.fd->type;
1592 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1595 fi = iptr->sx.s23.s3.fmiref->p.field;
1596 fieldtype = fi->type;
1600 switch (fieldtype) {
1602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1610 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1614 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1618 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1625 emit_store_dst(jd, iptr, d);
1628 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1630 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1631 emit_nullpointer_check(cd, iptr, s1);
1633 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1634 uf = iptr->sx.s23.s3.uf;
1635 fieldtype = uf->fieldref->parseddesc.fd->type;
1640 fi = iptr->sx.s23.s3.fmiref->p.field;
1641 fieldtype = fi->type;
1645 if (IS_INT_LNG_TYPE(fieldtype))
1646 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1648 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1650 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1651 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1653 switch (fieldtype) {
1655 M_IST(s2, s1, disp);
1658 M_STX(s2, s1, disp);
1661 M_AST(s2, s1, disp);
1664 M_FST(s2, s1, disp);
1667 M_DST(s2, s1, disp);
1675 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1676 /* val = value (in current instruction) */
1677 /* following NOP) */
1679 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1680 emit_nullpointer_check(cd, iptr, s1);
1682 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1683 unresolved_field *uf = iptr->sx.s23.s3.uf;
1685 fieldtype = uf->fieldref->parseddesc.fd->type;
1687 codegen_addpatchref(cd, PATCHER_get_putfield,
1690 if (opt_showdisassemble) {
1698 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1700 fieldtype = fi->type;
1706 switch (fieldtype) {
1708 M_IST(REG_ZERO, s1, disp);
1711 M_STX(REG_ZERO, s1, disp);
1714 M_AST(REG_ZERO, s1, disp);
1717 M_FST(REG_ZERO, s1, disp);
1720 M_DST(REG_ZERO, s1, disp);
1726 /* branch operations **************************************************/
1728 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1731 M_INTMOVE(s1, REG_ITMP2_XPTR);
1733 #ifdef ENABLE_VERIFIER
1734 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1735 unresolved_class *uc = iptr->sx.s23.s2.uc;
1737 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
1739 #endif /* ENABLE_VERIFIER */
1741 disp = dseg_add_functionptr(cd, asm_handle_exception);
1742 M_ALD(REG_ITMP1, REG_PV, disp);
1743 M_JMP(REG_ITMP3_XPC, REG_ITMP1, REG_ZERO);
1745 M_NOP; /* nop ensures that XPC is less than the end */
1746 /* of basic block */
1750 case ICMD_GOTO: /* ... ==> ... */
1751 case ICMD_RET: /* ... ==> ... */
1754 codegen_add_branch_ref(cd, iptr->dst.block);
1759 case ICMD_JSR: /* ... ==> ... */
1762 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
1767 case ICMD_IFNULL: /* ..., value ==> ... */
1769 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1771 codegen_add_branch_ref(cd, iptr->dst.block);
1775 case ICMD_IFNONNULL: /* ..., value ==> ... */
1777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1779 codegen_add_branch_ref(cd, iptr->dst.block);
1783 case ICMD_IFEQ: /* ..., value ==> ... */
1785 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1786 if (iptr->sx.val.i == 0) {
1789 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1790 M_CMP_IMM(s1, iptr->sx.val.i);
1793 ICONST(REG_ITMP2, iptr->sx.val.i);
1794 M_CMP(s1, REG_ITMP2);
1798 codegen_add_branch_ref(cd, iptr->dst.block);
1802 case ICMD_IFLT: /* ..., value ==> ... */
1804 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1805 if (iptr->sx.val.i == 0) {
1808 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1809 M_CMP_IMM(s1, iptr->sx.val.i);
1811 ICONST(REG_ITMP2, iptr->sx.val.i);
1812 M_CMP(s1, REG_ITMP2);
1816 codegen_add_branch_ref(cd, iptr->dst.block);
1820 case ICMD_IFLE: /* ..., value ==> ... */
1822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1823 if (iptr->sx.val.i == 0) {
1827 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1828 M_CMP_IMM(s1, iptr->sx.val.i);
1831 ICONST(REG_ITMP2, iptr->sx.val.i);
1832 M_CMP(s1, REG_ITMP2);
1836 codegen_add_branch_ref(cd, iptr->dst.block);
1840 case ICMD_IFNE: /* ..., value ==> ... */
1842 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1843 if (iptr->sx.val.i == 0) {
1847 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1848 M_CMP_IMM(s1, iptr->sx.val.i);
1851 ICONST(REG_ITMP2, iptr->sx.val.i);
1852 M_CMP(s1, REG_ITMP2);
1856 codegen_add_branch_ref(cd, iptr->dst.block);
1860 case ICMD_IFGT: /* ..., value ==> ... */
1862 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1863 if (iptr->sx.val.i == 0) {
1867 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1868 M_CMP_IMM(s1, iptr->sx.val.i);
1870 ICONST(REG_ITMP2, iptr->sx.val.i);
1871 M_CMP(s1, REG_ITMP2);
1875 codegen_add_branch_ref(cd, iptr->dst.block);
1879 case ICMD_IFGE: /* ..., value ==> ... */
1881 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1882 if (iptr->sx.val.i == 0) {
1886 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1887 M_CMP_IMM(s1, iptr->sx.val.i);
1890 ICONST(REG_ITMP2, iptr->sx.val.i);
1891 M_CMP(s1, REG_ITMP2);
1895 codegen_add_branch_ref(cd, iptr->dst.block);
1899 case ICMD_IF_LEQ: /* ..., value ==> ... */
1901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1902 if (iptr->sx.val.l == 0) {
1906 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1907 M_CMP_IMM(s1, iptr->sx.val.l);
1910 LCONST(REG_ITMP2, iptr->sx.val.l);
1911 M_CMP(s1, REG_ITMP2);
1915 codegen_add_branch_ref(cd, iptr->dst.block);
1919 case ICMD_IF_LLT: /* ..., value ==> ... */
1921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1922 if (iptr->sx.val.l == 0) {
1926 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1927 M_CMP_IMM(s1, iptr->sx.val.l);
1930 ICONST(REG_ITMP2, iptr->sx.val.l);
1931 M_CMP(s1, REG_ITMP2);
1935 codegen_add_branch_ref(cd, iptr->dst.block);
1939 case ICMD_IF_LLE: /* ..., value ==> ... */
1941 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1942 if (iptr->sx.val.l == 0) {
1946 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1947 M_CMP_IMM(s1, iptr->sx.val.l);
1950 ICONST(REG_ITMP2, iptr->sx.val.l);
1951 M_CMP(s1, REG_ITMP2);
1955 codegen_add_branch_ref(cd, iptr->dst.block);
1959 case ICMD_IF_LNE: /* ..., value ==> ... */
1961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1962 if (iptr->sx.val.l == 0) {
1966 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1967 M_CMP_IMM(s1, iptr->sx.val.i);
1970 ICONST(REG_ITMP2, iptr->sx.val.l);
1971 M_CMP(s1, REG_ITMP2);
1975 codegen_add_branch_ref(cd, iptr->dst.block);
1979 case ICMD_IF_LGT: /* ..., value ==> ... */
1981 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1982 if (iptr->sx.val.l == 0) {
1985 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1986 M_CMP_IMM(s1, iptr->sx.val.l);
1988 ICONST(REG_ITMP2, iptr->sx.val.l);
1989 M_CMP(s1, REG_ITMP2);
1993 codegen_add_branch_ref(cd, iptr->dst.block);
1997 case ICMD_IF_LGE: /* ..., value ==> ... */
1999 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2000 if (iptr->sx.val.l == 0) {
2004 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2005 M_CMP_IMM(s1, iptr->sx.val.l);
2008 ICONST(REG_ITMP2, iptr->sx.val.l);
2009 M_CMP(s1, REG_ITMP2);
2013 codegen_add_branch_ref(cd, iptr->dst.block);
2018 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2019 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2021 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2022 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2025 codegen_add_branch_ref(cd, iptr->dst.block);
2029 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2031 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2032 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2035 codegen_add_branch_ref(cd, iptr->dst.block);
2039 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2040 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2042 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2043 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2046 codegen_add_branch_ref(cd, iptr->dst.block);
2050 case ICMD_IF_ICMPNE: /* 32-bit compare */
2052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2056 codegen_add_branch_ref(cd, iptr->dst.block);
2060 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2063 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2066 codegen_add_branch_ref(cd, iptr->dst.block);
2070 case ICMD_IF_ICMPLT: /* 32-bit compare */
2072 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2073 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2076 codegen_add_branch_ref(cd, iptr->dst.block);
2080 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2082 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2083 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2086 codegen_add_branch_ref(cd, iptr->dst.block);
2090 case ICMD_IF_ICMPGT: /* 32-bit compare */
2092 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2093 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2096 codegen_add_branch_ref(cd, iptr->dst.block);
2100 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2103 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2106 codegen_add_branch_ref(cd, iptr->dst.block);
2110 case ICMD_IF_ICMPLE: /* 32-bit compare */
2112 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2113 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2116 codegen_add_branch_ref(cd, iptr->dst.block);
2121 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2123 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2124 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2127 codegen_add_branch_ref(cd, iptr->dst.block);
2131 case ICMD_IF_ICMPGE: /* 32-bit compare */
2133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2134 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2137 codegen_add_branch_ref(cd, iptr->dst.block);
2142 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2145 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2146 M_INTMOVE(s1, REG_RESULT_CALLEE);
2147 goto nowperformreturn;
2149 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2151 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2152 M_INTMOVE(s1, REG_RESULT_CALLEE);
2154 #ifdef ENABLE_VERIFIER
2155 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2156 unresolved_class *uc = iptr->sx.s23.s2.uc;
2158 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2160 #endif /* ENABLE_VERIFIER */
2161 goto nowperformreturn;
2163 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2166 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2167 M_DBLMOVE(s1, REG_FRESULT);
2168 goto nowperformreturn;
2170 case ICMD_RETURN: /* ... ==> ... */
2176 p = cd->stackframesize;
2178 #if !defined(NDEBUG)
2179 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2180 emit_verbosecall_exit(jd);
2183 #if defined(ENABLE_THREADS)
2184 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2185 /* XXX: REG_RESULT is save, but what about FRESULT? */
2186 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2188 switch (iptr->opc) {
2191 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2195 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2196 M_ALD(REG_ITMP3, REG_PV, disp);
2197 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2199 switch (iptr->opc) {
2202 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2210 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2216 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2219 branch_target_t *table;
2221 table = iptr->dst.table;
2223 l = iptr->sx.s23.s2.tablelow;
2224 i = iptr->sx.s23.s3.tablehigh;
2226 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2228 M_INTMOVE(s1, REG_ITMP1);
2230 else if (l <= 4095) {
2231 M_ADD_IMM(s1, -l, REG_ITMP1);
2234 ICONST(REG_ITMP2, l);
2235 /* XXX: do I need to truncate s1 to 32-bit ? */
2236 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2244 M_CMP_IMM(REG_ITMP1, i - 1);
2247 ICONST(REG_ITMP2, i - 1);
2248 M_CMP(REG_ITMP1, REG_ITMP2);
2251 codegen_add_branch_ref(cd, table[0].block); /* default target */
2252 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2254 /* build jump table top down and use address of lowest entry */
2259 dseg_add_target(cd, table->block);
2264 /* length of dataseg after last dseg_addtarget is used by load */
2266 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2267 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2268 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2273 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2276 lookup_target_t *lookup;
2278 lookup = iptr->dst.lookup;
2280 i = iptr->sx.s23.s2.lookupcount;
2282 MCODECHECK((i<<2)+8);
2283 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2286 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2287 M_CMP_IMM(s1, lookup->value);
2289 ICONST(REG_ITMP2, lookup->value);
2290 M_CMP(s1, REG_ITMP2);
2293 codegen_add_branch_ref(cd, lookup->target.block);
2299 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2306 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2308 bte = iptr->sx.s23.s3.bte;
2311 /* XXX: proper builtin calling and float args are so not implemented */
2312 assert(md->paramcount <= 5 && md->argfltreguse < 1);
2316 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2318 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2319 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2320 case ICMD_INVOKEINTERFACE:
2322 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2324 um = iptr->sx.s23.s3.um;
2325 md = um->methodref->parseddesc.md;
2328 lm = iptr->sx.s23.s3.fmiref->p.method;
2330 md = lm->parseddesc;
2334 s3 = md->paramcount;
2336 MCODECHECK((s3 << 1) + 64);
2338 /* copy arguments to registers or stack location */
2340 for (s3 = s3 - 1; s3 >= 0; s3--) {
2341 var = VAR(iptr->sx.s23.s2.args[s3]);
2343 if (var->flags & PREALLOC)
2346 if (IS_INT_LNG_TYPE(var->type)) {
2347 if (!md->params[s3].inmemory) {
2348 s1 = rd->argintregs[md->params[s3].regoff];
2349 d = emit_load(jd, iptr, var, s1);
2353 d = emit_load(jd, iptr, var, REG_ITMP1);
2354 M_STX(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2358 if (!md->params[s3].inmemory) {
2359 s1 = rd->argfltregs[md->params[s3].regoff];
2360 d = emit_load(jd, iptr, var, s1);
2361 if (IS_2_WORD_TYPE(var->type))
2367 d = emit_load(jd, iptr, var, REG_FTMP1);
2368 if (IS_2_WORD_TYPE(var->type))
2369 M_DST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2371 M_FST(d, REG_SP, JITSTACK + md->params[s3].regoff * 8);
2376 switch (iptr->opc) {
2378 disp = dseg_add_functionptr(cd, bte->fp);
2380 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2383 /* XXX jit-c-call */
2387 case ICMD_INVOKESPECIAL:
2388 M_BEQZ(REG_OUT0, 0);
2389 codegen_add_nullpointerexception_ref(cd);
2393 case ICMD_INVOKESTATIC:
2395 disp = dseg_add_unique_address(cd, NULL);
2397 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2401 disp = dseg_add_address(cd, lm->stubroutine);
2403 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2407 case ICMD_INVOKEVIRTUAL:
2408 emit_nullpointer_check(cd, iptr, REG_OUT0);
2411 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
2416 s1 = OFFSET(vftbl_t, table[0]) +
2417 sizeof(methodptr) * lm->vftblindex;
2419 M_ALD(REG_METHODPTR, REG_OUT0,
2420 OFFSET(java_objectheader, vftbl));
2421 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2425 case ICMD_INVOKEINTERFACE:
2426 emit_nullpointer_check(cd, iptr, REG_OUT0);
2429 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
2435 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2436 sizeof(methodptr*) * lm->class->index;
2438 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2441 M_ALD(REG_METHODPTR, REG_OUT0,
2442 OFFSET(java_objectheader, vftbl));
2443 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2444 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2449 /* generate the actual call */
2451 M_JMP(REG_RA_CALLER, s1, REG_ZERO);
2453 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2454 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2455 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2458 /* actually only used for ICMD_BUILTIN */
2460 if (INSTRUCTION_MUST_CHECK(iptr)) {
2461 M_BEQZ(REG_RESULT_CALLER, 0);
2462 codegen_add_fillinstacktrace_ref(cd);
2466 /* store return value */
2468 d = md->returntype.type;
2470 if (d != TYPE_VOID) {
2471 if (IS_INT_LNG_TYPE(d)) {
2472 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2473 M_INTMOVE(REG_RESULT_CALLER, s1);
2476 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2477 if (IS_2_WORD_TYPE(d)) {
2478 M_DBLMOVE(REG_FRESULT, s1);
2480 M_FLTMOVE(REG_FRESULT, s1);
2483 emit_store_dst(jd, iptr, s1);
2488 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2489 /* val.a: (classinfo*) superclass */
2491 /* superclass is an interface:
2493 * OK if ((sub == NULL) ||
2494 * (sub->vftbl->interfacetablelength > super->index) &&
2495 * (sub->vftbl->interfacetable[-super->index] != NULL));
2497 * superclass is a class:
2499 * OK if ((sub == NULL) || (0
2500 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2501 * super->vftbl->diffvall));
2504 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2508 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2513 super = iptr->sx.s23.s3.c.cls;
2514 superindex = super->index;
2517 #if defined(ENABLE_THREADS)
2518 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2523 /* calculate interface checkcast code size */
2527 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2529 /* calculate class checkcast code size */
2533 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2535 /* if class is not resolved, check which code to call */
2537 if (super == NULL) {
2538 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3 + 1);
2541 cr = iptr->sx.s23.s3.c.ref;
2542 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2544 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2547 M_ILD(REG_ITMP2, REG_PV, disp);
2548 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2549 M_BEQZ(REG_ITMP2, s2 + 2 + 2);
2553 /* interface checkcast code */
2555 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2556 if (super == NULL) {
2557 cr = iptr->sx.s23.s3.c.ref;
2559 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
2567 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2568 M_ILD(REG_ITMP3, REG_ITMP2,
2569 OFFSET(vftbl_t, interfacetablelength));
2570 M_ADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
2571 M_BLEZ(REG_ITMP3, 0);
2572 codegen_add_classcastexception_ref(cd, s1);
2574 M_ALD(REG_ITMP3, REG_ITMP2,
2575 OFFSET(vftbl_t, interfacetable[0]) -
2576 superindex * sizeof(methodptr*));
2577 M_BEQZ(REG_ITMP3, 0);
2578 codegen_add_classcastexception_ref(cd, s1);
2581 if (super == NULL) {
2582 /* on sparc we always add 2 to the size of the code we want */
2583 /* branch over. (1 for branch delay nop, 1 since the base is */
2584 /* the address of the branch instruction */
2590 /* class checkcast code */
2592 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2593 if (super == NULL) {
2594 cr = iptr->sx.s23.s3.c.ref;
2595 disp = dseg_add_unique_address(cd, NULL);
2597 codegen_add_patch_ref(cd,
2598 PATCHER_checkcast_instanceof_class,
2602 disp = dseg_add_address(cd, super->vftbl);
2608 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2609 M_ALD(REG_ITMP3, REG_PV, disp);
2610 #if defined(ENABLE_THREADS)
2611 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2613 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2614 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2615 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2616 M_ALD(REG_ITMP3, REG_PV, disp);
2617 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2618 #if defined(ENABLE_THREADS)
2619 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2622 M_CMP(REG_ITMP3, REG_ITMP2);
2623 M_BULT(0); /* branch if ITMP3 < ITMP2 */
2624 codegen_add_classcastexception_ref(cd, s1);
2628 d = codegen_reg_of_dst(jd, iptr, s1);
2631 /* array type cast-check */
2633 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
2634 M_INTMOVE(s1, rd->argintregs[0]);
2636 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2638 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2639 cr = iptr->sx.s23.s3.c.ref;
2640 disp = dseg_add_unique_address(cd, NULL);
2642 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
2646 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2648 M_ALD(rd->argintregs[1], REG_PV, disp);
2649 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2650 M_ALD(REG_ITMP3, REG_PV, disp);
2651 /* XXX jit-c-call */
2652 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2655 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2656 M_BEQZ(REG_RESULT_CALLER, 0);
2657 codegen_add_classcastexception_ref(cd, s1);
2660 d = codegen_reg_of_dst(jd, iptr, s1);
2664 emit_store_dst(jd, iptr, d);
2667 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
2669 /* superclass is an interface:
2671 * return (sub != NULL) &&
2672 * (sub->vftbl->interfacetablelength > super->index) &&
2673 * (sub->vftbl->interfacetable[-super->index] != NULL);
2675 * superclass is a class:
2677 * return ((sub != NULL) && (0
2678 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2679 * super->vftbl->diffvall));
2684 vftbl_t *supervftbl;
2687 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2693 super = iptr->sx.s23.s3.c.cls;
2694 superindex = super->index;
2695 supervftbl = super->vftbl;
2698 #if defined(ENABLE_THREADS)
2699 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2704 M_MOV(s1, REG_ITMP1);
2708 /* calculate interface instanceof code size */
2712 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2714 /* calculate class instanceof code size */
2718 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
2722 /* if class is not resolved, check which code to call */
2724 if (super == NULL) {
2725 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
2728 cr = iptr->sx.s23.s3.c.ref;
2729 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2731 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
2734 M_ILD(REG_ITMP3, REG_PV, disp);
2735 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
2736 M_BEQZ(REG_ITMP3, s2 + 2 + 2);
2740 /* interface instanceof code */
2742 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2743 if (super == NULL) {
2744 cr = iptr->sx.s23.s3.c.ref;
2746 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
2754 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2755 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
2756 M_CMP_IMM(REG_ITMP3, superindex);
2759 M_ALD(REG_ITMP1, REG_ITMP1,
2760 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2761 superindex * sizeof(methodptr*)));
2762 M_CMOVRNE_IMM(REG_ITMP1, 1, d); /* REG_ITMP1 != 0 */
2764 if (super == NULL) {
2770 /* class instanceof code */
2772 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2773 if (super == NULL) {
2774 cr = iptr->sx.s23.s3.c.ref;
2775 disp = dseg_add_unique_address(cd, NULL);
2777 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
2781 disp = dseg_add_address(cd, supervftbl);
2787 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
2788 M_ALD(REG_ITMP2, REG_PV, disp);
2789 #if defined(ENABLE_THREADS)
2790 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2792 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
2793 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
2794 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
2795 #if defined(ENABLE_THREADS)
2796 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2798 M_SUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
2799 M_CMP(REG_ITMP1, REG_ITMP2);
2800 M_XCMOVULE_IMM(1, d);
2802 emit_store_dst(jd, iptr, d);
2806 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
2808 /* check for negative sizes and copy sizes to stack if necessary */
2810 MCODECHECK((iptr->s1.argcount << 1) + 64);
2812 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
2814 var = VAR(iptr->sx.s23.s2.args[s1]);
2816 /* copy SAVEDVAR sizes to stack */
2818 /* Already Preallocated? */
2820 if (!(var->flags & PREALLOC)) {
2821 s2 = emit_load(jd, iptr, var, REG_ITMP1);
2822 M_STX(s2, REG_SP, CSTACK + (s1 * 8));
2826 /* arg 0 = dimension count */
2828 ICONST(REG_OUT0, iptr->s1.argcount);
2830 /* is patcher function set? */
2832 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2833 disp = dseg_add_unique_address(cd, 0);
2835 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
2836 iptr->sx.s23.s3.c.ref,
2840 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2842 /* arg 1 = arraydescriptor */
2844 M_ALD(REG_OUT1, REG_PV, disp);
2846 /* arg 2 = pointer to dimensions = stack pointer (absolute) */
2848 M_ADD_IMM(REG_SP, CSTACK, REG_OUT2);
2850 /* XXX c abi call */
2851 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
2852 M_ALD(REG_ITMP3, REG_PV, disp);
2853 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2856 /* check for exception before result assignment */
2858 M_BEQZ(REG_RESULT_CALLER, 0);
2859 codegen_add_fillinstacktrace_ref(cd);
2862 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2863 M_INTMOVE(REG_RESULT_CALLER, d);
2864 emit_store_dst(jd, iptr, d);
2868 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
2874 } /* for instruction */
2878 } /* if (bptr -> flags >= BBREACHED) */
2879 } /* for basic block */
2881 dseg_createlinenumbertable(cd);
2883 /* generate exception and patcher stubs */
2885 emit_exception_stubs(jd);
2886 emit_patcher_stubs(jd);
2887 #if defined(ENABLE_REPLACEMENT)
2888 emit_replacement_stubs(jd);
2889 #endif /* defined(ENABLE_REPLACEMENT) */
2893 /* everything's ok */
2902 /* createcompilerstub **********************************************************
2904 Creates a stub routine which calls the compiler.
2906 *******************************************************************************/
2908 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
2909 #define COMPILERSTUB_CODESIZE 4 * 4
2911 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2914 u1 *createcompilerstub(methodinfo *m)
2916 u1 *s; /* memory to hold the stub */
2922 s = CNEW(u1, COMPILERSTUB_SIZE);
2924 /* set data pointer and code pointer */
2927 s = s + COMPILERSTUB_DATASIZE;
2929 /* mark start of dump memory area */
2931 dumpsize = dump_size();
2933 cd = DNEW(codegendata);
2936 /* Store the codeinfo pointer in the same place as in the
2937 methodheader for compiled methods. */
2939 code = code_codeinfo_new(m);
2941 d[0] = (ptrint) asm_call_jit_compiler;
2943 d[2] = (ptrint) code;
2945 /* code for the stub */
2946 /* no window save yet, user caller's PV */
2947 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2948 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2949 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2952 #if defined(ENABLE_STATISTICS)
2954 count_cstub_len += COMPILERSTUB_SIZE;
2957 /* release dump area */
2959 dump_release(dumpsize);
2966 /* createnativestub ************************************************************
2968 Creates a stub routine which calls a native method.
2970 *******************************************************************************/
2972 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2980 s4 i, j; /* count variables */
2983 s4 funcdisp; /* displacement of the function */
2985 /* get required compiler data */
2992 /* redo param allocation */
2993 md_native_param_alloc(nmd);
2995 /* initialize variables */
2998 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3000 /* calculate stack frame size */
3002 cd->stackframesize =
3003 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3004 sizeof(localref_table) / SIZEOF_VOID_P +
3005 md->paramcount + /* for saving arguments over calls */
3006 nmd->memuse + /* nmd knows about the native stackframe layout */
3009 /* create method header */
3011 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3012 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3013 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3014 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3015 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3016 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3017 (void) dseg_addlinenumbertablesize(cd);
3018 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3020 /* generate stub code */
3022 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
3024 #if !defined(NDEBUG)
3025 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3026 emit_verbosecall_enter(jd);
3029 /* get function address (this must happen before the stackframeinfo) */
3031 funcdisp = dseg_add_functionptr(cd, f);
3033 #if !defined(WITH_STATIC_CLASSPATH)
3035 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3039 /* save float argument registers */
3041 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3042 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3043 M_DST(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
3048 /* prepare data structures for native function call */
3050 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
3051 M_MOV(REG_PV_CALLEE, REG_OUT1);
3052 M_MOV(REG_FP, REG_OUT2); /* java sp */
3053 M_MOV(REG_RA_CALLEE, REG_OUT3);
3054 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3055 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3056 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3057 M_NOP; /* XXX fill me! */
3059 /* restore float argument registers */
3061 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3062 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
3063 M_DLD(rd->argfltregs[i], REG_SP, CSTACK + (j * 8));
3068 /* copy or spill arguments to new locations */
3069 int num_fltregargs = 0;
3070 int fltregarg_inswap[16];
3071 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3072 t = md->paramtypes[i].type;
3074 if (IS_INT_LNG_TYPE(t)) {
3075 if (!md->params[i].inmemory) {
3076 s1 = rd->argintregs[md->params[i].regoff];
3077 /* s1 refers to the old window, transpose */
3078 s1 = REG_WINDOW_TRANSPOSE(s1);
3080 if (!nmd->params[j].inmemory) {
3081 s2 = nat_argintregs[nmd->params[j].regoff];
3084 s2 = nmd->params[j].regoff - 6;
3085 M_AST(s1, REG_SP, CSTACK + s2 * 8);
3089 s1 = md->params[i].regoff + cd->stackframesize;
3090 s2 = nmd->params[j].regoff - 6;
3091 M_ALD(REG_ITMP1, REG_SP, CSTACK + s1 * 8);
3092 M_AST(REG_ITMP1, REG_SP, CSTACK + s2 * 8);
3096 if (!md->params[i].inmemory) {
3097 s1 = rd->argfltregs[md->params[i].regoff];
3099 if (!nmd->params[j].inmemory) {
3100 /* no mapping to regs needed, native flt args use regoff */
3101 s2 = nmd->params[j].regoff;
3103 /* we cannot move flt regs to their native arg locations directly */
3104 M_DMOV(s1, s2 + 16);
3105 fltregarg_inswap[num_fltregargs] = s2;
3107 printf("flt arg swap to %d\n", s2 + 16);
3110 s2 = nmd->params[j].regoff;
3111 if (IS_2_WORD_TYPE(t))
3112 M_DST(s1, REG_SP, CSTACK + (s2 * 8));
3114 M_FST(s1, REG_SP, CSTACK + (s2 * 8));
3118 s1 = md->params[i].regoff + cd->stackframesize;
3119 s2 = nmd->params[j].regoff - 6;
3120 if (IS_2_WORD_TYPE(t)) {
3121 M_DLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3122 M_DST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3124 M_FLD(REG_FTMP1, REG_SP, CSTACK + s1 * 8);
3125 M_FST(REG_FTMP1, REG_SP, CSTACK + s2 * 8);
3131 /* move swapped float args to target regs */
3132 for (i = 0; i < num_fltregargs; i++) {
3133 s1 = fltregarg_inswap[i];
3134 M_DMOV(s1 + 16, s1);
3135 printf("float arg to target reg: %d ==> %d\n", s1+16, s1);
3139 /* put class into second argument register */
3141 if (m->flags & ACC_STATIC) {
3142 disp = dseg_add_address(cd, m->class);
3143 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3146 /* put env into first argument register */
3148 disp = dseg_add_address(cd, _Jv_env);
3149 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3151 /* do the native function call */
3153 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3154 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3155 M_NOP; /* delay slot */
3157 /* save return value */
3159 if (md->returntype.type != TYPE_VOID) {
3160 if (IS_INT_LNG_TYPE(md->returntype.type))
3161 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3163 M_DST(REG_FRESULT, REG_SP, CSTACK);
3166 /* Note: native functions return float values in %f0 (see ABI) */
3167 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3169 #if !defined(NDEBUG)
3170 /* But for the trace function we need to put a flt result into %f1 */
3171 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3172 if (!IS_2_WORD_TYPE(md->returntype.type))
3173 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3174 emit_verbosecall_exit(jd);
3178 /* remove native stackframe info */
3180 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3181 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3182 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3183 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3184 M_NOP; /* XXX fill me! */
3185 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3187 /* restore float return value, int return value already in our return reg */
3189 if (md->returntype.type != TYPE_VOID) {
3190 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3191 if (IS_2_WORD_TYPE(md->returntype.type))
3192 M_DLD(REG_FRESULT, REG_SP, CSTACK);
3194 M_FLD(REG_FRESULT, REG_SP, CSTACK);
3198 /* check for exception */
3200 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3203 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
3206 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3208 M_RET(REG_RA_CALLER, 8); /* return to caller */
3209 M_NOP; /* DELAY SLOT */
3212 /* handle exception */
3214 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3215 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3216 M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);/* jump to asm exception handler */
3217 M_MOV(REG_RA_CALLEE, REG_ITMP3_XPC); /* get exception address (DELAY) */
3219 /* generate patcher stubs */
3221 emit_patcher_stubs(jd);
3225 return code->entrypoint;
3229 * These are local overrides for various environment variables in Emacs.
3230 * Please do not remove this and leave it at the end of the file, where
3231 * Emacs will automagically detect them.
3232 * ---------------------------------------------------------------------
3235 * indent-tabs-mode: t
3239 * vim:noexpandtab:sw=4:ts=4: