1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
33 $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
44 /* #include "vm/jit/sparc64/arch.h" */
45 #include "vm/jit/sparc64/codegen.h"
47 #include "mm/memory.h"
49 #include "native/jni.h"
50 #include "native/native.h"
51 #include "vm/builtin.h"
52 #include "vm/exceptions.h"
53 #include "vm/global.h"
54 #include "vm/loader.h"
55 #include "vm/options.h"
56 #include "vm/stringlocal.h"
57 #include "vm/jit/asmpart.h"
58 #include "vm/jit/codegen-common.h"
59 #include "vm/jit/dseg.h"
60 #include "vm/jit/emit.h"
61 #include "vm/jit/jit.h"
62 #include "vm/jit/parse.h"
63 #include "vm/jit/patcher.h"
64 #include "vm/jit/reg.h"
67 #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
69 static int fabort(char *x)
71 fprintf(stderr, "sparc64 abort because: %s\n", x);
79 bool codegen(jitdata *jd)
84 s4 len, s1, s2, s3, d, disp;
93 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
94 builtintable_entry *bte;
96 rplpoint *replacementpoint;
98 bool own_window = true; /* currently assumes immediate save*/
100 /* get required compiler data */
107 (void) dseg_addaddress(cd, m); /* MethodPointer */
108 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
110 #if defined(USE_THREADS)
111 /* IsSync contains the offset relative to the stack pointer for the
112 argument of monitor_exit used in the exception handler. Since the
113 offset could be zero and give a wrong meaning of the flag it is
117 if (checksync && (m->flags & ACC_SYNCHRONIZED))
118 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
121 (void) dseg_adds4(cd, 0); /* IsSync */
123 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
124 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
125 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
128 dseg_addlinenumbertablesize(cd);
130 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
135 /* XXX create exception table */
137 /* initialize mcode variables */
138 mcodeptr = (s4 *) cd->mcodeptr;
141 /* XXX stack setup */
144 /* XXX copy arguments */
147 /* XXX monitor enter and tracing */
150 /* end of header generation */
152 replacementpoint = jd->code->rplpoints;
154 /* walk through all basic blocks */
156 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
158 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
160 if (bptr->flags >= BBREACHED) {
162 /* branch resolving */
166 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
167 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
168 brefs->branchpos, bptr->mpc);
172 /* handle replacement points */
174 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
175 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
180 /* copy interface registers to their destination */
186 #if defined(ENABLE_LSRA)
188 while (src != NULL) {
190 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
191 /* d = reg_of_var(m, src, REG_ITMP1); */
192 if (!(src->flags & INMEMORY))
196 M_INTMOVE(REG_ITMP1, d);
197 emit_store(jd, NULL, src, d);
203 while (src != NULL) {
205 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
206 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
207 M_INTMOVE(REG_ITMP1, d);
208 emit_store(jd, NULL, src, d);
211 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
212 if ((src->varkind != STACKVAR)) {
214 if (IS_FLT_DBL_TYPE(s2)) {
215 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
216 s1 = rd->interfaces[len][s2].regoff;
219 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
221 emit_store(jd, NULL, src, d);
224 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
225 s1 = rd->interfaces[len][s2].regoff;
228 M_LDX(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
230 emit_store(jd, NULL, src, d);
236 #if defined(ENABLE_LSRA)
240 /* walk through all instructions */
245 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
246 if (iptr->line != currentline) {
247 dseg_addlinenumber(cd, iptr->line);
248 currentline = iptr->line;
251 MCODECHECK(64); /* an instruction usually needs < 64 words */
254 case ICMD_INLINE_START:
255 case ICMD_INLINE_END:
258 case ICMD_NOP: /* ... ==> ... */
261 /* constant operations ************************************************/
263 case ICMD_ICONST: /* ... ==> ..., constant */
264 /* op1 = 0, val.i = constant */
266 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
267 ICONST(d, iptr->val.i);
268 emit_store(jd, iptr, iptr->dst, d);
271 case ICMD_LCONST: /* ... ==> ..., constant */
272 /* op1 = 0, val.l = constant */
274 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
275 LCONST(d, iptr->val.l);
276 emit_store(jd, iptr, iptr->dst, d);
279 case ICMD_FCONST: /* ... ==> ..., constant */
280 /* op1 = 0, val.f = constant */
282 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
283 disp = dseg_addfloat(cd, iptr->val.f);
284 M_FLD(d, REG_PV, disp);
285 emit_store(jd, iptr, iptr->dst, d);
288 case ICMD_DCONST: /* ... ==> ..., constant */
289 /* op1 = 0, val.d = constant */
291 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
292 disp = dseg_adddouble(cd, iptr->val.d);
293 M_DLD(d, REG_PV, disp);
294 emit_store(jd, iptr, iptr->dst, d);
297 case ICMD_ACONST: /* ... ==> ..., constant */
298 /* op1 = 0, val.a = constant */
300 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
302 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
303 disp = dseg_addaddress(cd, iptr->val.a);
305 codegen_addpatchref(cd, PATCHER_aconst,
306 (unresolved_class *) iptr->target, disp);
308 if (opt_showdisassemble) {
312 M_ALD(REG_PV, disp, d);
315 if (iptr->val.a == NULL) {
316 M_INTMOVE(REG_ZERO, d);
318 disp = dseg_addaddress(cd, iptr->val.a);
319 M_ALD(d, REG_PV, disp);
322 emit_store(jd, iptr, iptr->dst, d);
326 /* load/store operations **********************************************/
328 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
329 case ICMD_LLOAD: /* op1 = local variable */
332 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
333 if ((iptr->dst->varkind == LOCALVAR) &&
334 (iptr->dst->varnum == iptr->op1))
336 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
337 if (var->flags & INMEMORY) {
338 M_ALD(REG_SP, var->regoff * 8, d);
340 M_INTMOVE(var->regoff, d);
342 emit_store(jd, iptr, iptr->dst, d);
345 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
346 case ICMD_DLOAD: /* op1 = local variable */
348 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
349 if ((iptr->dst->varkind == LOCALVAR) &&
350 (iptr->dst->varnum == iptr->op1))
352 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
353 if (var->flags & INMEMORY) {
354 M_DLD(d, REG_SP, var->regoff * 8);
356 M_FLTMOVE(var->regoff, d);
358 emit_store(jd, iptr, iptr->dst, d);
362 case ICMD_ISTORE: /* ..., value ==> ... */
363 case ICMD_LSTORE: /* op1 = local variable */
366 if ((src->varkind == LOCALVAR) &&
367 (src->varnum == iptr->op1))
369 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
370 if (var->flags & INMEMORY) {
371 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
372 M_STX(s1, REG_SP, var->regoff * 8);
374 s1 = emit_load_s1(jd, iptr, src, var->regoff);
375 M_INTMOVE(s1, var->regoff);
379 case ICMD_FSTORE: /* ..., value ==> ... */
380 case ICMD_DSTORE: /* op1 = local variable */
382 if ((src->varkind == LOCALVAR) &&
383 (src->varnum == iptr->op1))
385 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
386 if (var->flags & INMEMORY) {
387 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
388 M_DST(s1, REG_SP, var->regoff * 8);
390 s1 = emit_load_s1(jd, iptr, src, var->regoff);
391 M_FLTMOVE(s1, var->regoff);
396 /* pop/dup/swap operations ********************************************/
398 /* attention: double and longs are only one entry in CACAO ICMDs */
400 case ICMD_POP: /* ..., value ==> ... */
401 case ICMD_POP2: /* ..., value, value ==> ... */
404 case ICMD_DUP: /* ..., a ==> ..., a, a */
405 M_COPY(src, iptr->dst);
408 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
410 M_COPY(src, iptr->dst);
411 M_COPY(src->prev, iptr->dst->prev);
412 M_COPY(iptr->dst, iptr->dst->prev->prev);
415 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
417 M_COPY(src, iptr->dst);
418 M_COPY(src->prev, iptr->dst->prev);
419 M_COPY(src->prev->prev, iptr->dst->prev->prev);
420 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
423 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
425 M_COPY(src, iptr->dst);
426 M_COPY(src->prev, iptr->dst->prev);
429 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
431 M_COPY(src, iptr->dst);
432 M_COPY(src->prev, iptr->dst->prev);
433 M_COPY(src->prev->prev, iptr->dst->prev->prev);
434 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
435 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
438 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
440 M_COPY(src, iptr->dst);
441 M_COPY(src->prev, iptr->dst->prev);
442 M_COPY(src->prev->prev, iptr->dst->prev->prev);
443 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
444 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
445 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
448 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
450 M_COPY(src, iptr->dst->prev);
451 M_COPY(src->prev, iptr->dst);
455 /* integer operations *************************************************/
457 case ICMD_INEG: /* ..., value ==> ..., - value */
460 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
461 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
462 M_SUB(REG_ZERO, s1, d);
463 emit_store(jd, iptr, iptr->dst, d);
466 case ICMD_I2L: /* ..., value ==> ..., value */
468 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
469 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
471 emit_store(jd, iptr, iptr->dst, d);
474 case ICMD_L2I: /* ..., value ==> ..., value */
476 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
477 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
478 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
479 emit_store(jd, iptr, iptr->dst, d);
482 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
484 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
485 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
486 M_SLLX_IMM(s1, 56, d);
487 M_SRAX_IMM( d, 56, d);
488 emit_store(jd, iptr, iptr->dst, d);
491 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
494 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
495 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
496 M_SLLX_IMM(s1, 48, d);
497 M_SRAX_IMM( d, 48, d);
498 emit_store(jd, iptr, iptr->dst, d);
501 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
504 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
505 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
506 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
508 emit_store(jd, iptr, iptr->dst, d);
511 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
512 /* val.i = constant */
514 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
515 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
516 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
517 M_ADD_IMM(s1, iptr->val.i, d);
519 ICONST(REG_ITMP2, iptr->val.i);
520 M_ADD(s1, REG_ITMP2, d);
522 emit_store(jd, iptr, iptr->dst, d);
525 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
526 /* val.l = constant */
528 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
529 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
530 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
531 M_ADD_IMM(s1, iptr->val.l, d);
533 LCONST(REG_ITMP2, iptr->val.l);
534 M_ADD(s1, REG_ITMP2, d);
536 emit_store(jd, iptr, iptr->dst, d);
539 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
542 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
543 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
544 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
546 emit_store(jd, iptr, iptr->dst, d);
549 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
550 /* val.i = constant */
552 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
553 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
554 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
555 M_SUB_IMM(s1, iptr->val.i, d);
557 ICONST(REG_ITMP2, iptr->val.i);
558 M_SUB(s1, REG_ITMP2, d);
560 emit_store(jd, iptr, iptr->dst, d);
563 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
564 /* val.l = constant */
566 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
567 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
568 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
569 M_SUB_IMM(s1, iptr->val.l, d);
571 LCONST(REG_ITMP2, iptr->val.l);
572 M_SUB(s1, REG_ITMP2, d);
574 emit_store(jd, iptr, iptr->dst, d);
577 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
580 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
581 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
582 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
584 emit_store(jd, iptr, iptr->dst, d);
587 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
588 /* val.i = constant */
590 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
591 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
592 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
593 M_MULX_IMM(s1, iptr->val.i, d);
595 ICONST(REG_ITMP2, iptr->val.i);
596 M_MULX(s1, REG_ITMP2, d);
598 emit_store(jd, iptr, iptr->dst, d);
601 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
602 /* val.l = constant */
604 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
605 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
606 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
607 M_MULX_IMM(s1, iptr->val.l, d);
609 LCONST(REG_ITMP2, iptr->val.l);
610 M_MULX(s1, REG_ITMP2, d);
612 emit_store(jd, iptr, iptr->dst, d);
615 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
616 /* XXX could also clear Y and use 32bit div */
617 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
618 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
619 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
622 /* XXX trim s2 like s1 ? */
624 emit_store(jd, iptr, iptr->dst, d);
627 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
629 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
630 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
631 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
634 emit_store(jd, iptr, iptr->dst, d);
637 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
639 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
640 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
641 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
644 /* XXX trim s2 like s1 ? */
648 emit_store(jd, iptr, iptr->dst, d);
651 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
653 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
654 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
655 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
660 emit_store(jd, iptr, iptr->dst, d);
663 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
664 case ICMD_LDIVPOW2: /* val.i = constant */
666 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
667 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
668 M_SRAX_IMM(s1, 63, REG_ITMP2);
669 M_SRLX_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
670 M_ADD(s1, REG_ITMP2, REG_ITMP2);
671 M_SRAX_IMM(REG_ITMP2, iptr->val.i, d);
672 emit_store(jd, iptr, iptr->dst, d);
675 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
678 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
679 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
680 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
682 emit_store(jd, iptr, iptr->dst, d);
685 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
686 case ICMD_LSHLCONST: /* val.i = constant */
688 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
689 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
690 M_SLLX_IMM(s1, iptr->val.i, d);
691 emit_store(jd, iptr, iptr->dst, d);
694 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
696 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
697 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
698 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
700 emit_store(jd, iptr, iptr->dst, d);
703 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
704 /* val.i = constant */
706 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
707 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
708 M_SRA_IMM(s1, iptr->val.i, d);
709 emit_store(jd, iptr, iptr->dst, d);
712 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
714 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
715 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
716 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
718 emit_store(jd, iptr, iptr->dst, d);
721 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
722 /* val.i = constant */
724 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
725 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
726 M_SRL_IMM(s1, iptr->val.i, d);
727 emit_store(jd, iptr, iptr->dst, d);
730 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
732 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
733 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
734 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
736 emit_store(jd, iptr, iptr->dst, d);
739 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
740 /* val.i = constant */
742 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
743 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
744 M_SRAX_IMM(s1, iptr->val.i, d);
745 emit_store(jd, iptr, iptr->dst, d);
748 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
750 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
751 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
752 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
754 emit_store(jd, iptr, iptr->dst, d);
757 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
758 /* val.i = constant */
760 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
761 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
762 M_SRLX_IMM(s1, iptr->val.i, d);
763 emit_store(jd, iptr, iptr->dst, d);
766 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
769 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
770 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
771 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
773 emit_store(jd, iptr, iptr->dst, d);
776 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
777 /* val.i = constant */
779 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
780 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
781 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
782 M_AND_IMM(s1, iptr->val.i, d);
784 ICONST(REG_ITMP2, iptr->val.i);
785 M_AND(s1, REG_ITMP2, d);
787 emit_store(jd, iptr, iptr->dst, d);
790 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
791 /* val.i = constant */
793 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
794 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
795 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
797 M_MOV(s1, REG_ITMP1);
800 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
801 M_AND_IMM(s1, iptr->val.i, d);
804 M_SUB(REG_ZERO, s1, d);
805 M_AND_IMM(d, iptr->val.i, d);
807 ICONST(REG_ITMP2, iptr->val.i);
808 M_AND(s1, REG_ITMP2, d);
811 M_SUB(REG_ZERO, s1, d);
812 M_AND(d, REG_ITMP2, d);
814 M_SUB(REG_ZERO, d, d);
815 emit_store(jd, iptr, iptr->dst, d);
818 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
819 /* val.l = constant */
821 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
822 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
823 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
824 M_AND_IMM(s1, iptr->val.l, d);
826 LCONST(REG_ITMP2, iptr->val.l);
827 M_AND(s1, REG_ITMP2, d);
829 emit_store(jd, iptr, iptr->dst, d);
832 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
833 /* val.l = constant */
835 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
836 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
838 M_MOV(s1, REG_ITMP1);
841 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
842 M_AND_IMM(s1, iptr->val.l, d);
845 M_SUB(REG_ZERO, s1, d);
846 M_AND_IMM(d, iptr->val.l, d);
848 LCONST(REG_ITMP2, iptr->val.l);
849 M_AND(s1, REG_ITMP2, d);
852 M_SUB(REG_ZERO, s1, d);
853 M_AND(d, REG_ITMP2, d);
855 M_SUB(REG_ZERO, d, d);
856 emit_store(jd, iptr, iptr->dst, d);
859 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
862 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
863 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
864 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
866 emit_store(jd, iptr, iptr->dst, d);
869 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
870 /* val.i = constant */
872 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
873 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
874 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
875 M_OR_IMM(s1, iptr->val.i, d);
877 ICONST(REG_ITMP2, iptr->val.i);
878 M_OR(s1, REG_ITMP2, d);
880 emit_store(jd, iptr, iptr->dst, d);
883 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
884 /* val.l = constant */
886 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
887 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
888 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
889 M_OR_IMM(s1, iptr->val.l, d);
891 LCONST(REG_ITMP2, iptr->val.l);
892 M_OR(s1, REG_ITMP2, d);
894 emit_store(jd, iptr, iptr->dst, d);
897 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
900 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
901 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
902 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
904 emit_store(jd, iptr, iptr->dst, d);
907 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
908 /* val.i = constant */
910 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
911 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
912 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
913 M_XOR_IMM(s1, iptr->val.i, d);
915 ICONST(REG_ITMP2, iptr->val.i);
916 M_XOR(s1, REG_ITMP2, d);
918 emit_store(jd, iptr, iptr->dst, d);
921 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
922 /* val.l = constant */
924 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
925 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
926 if ((iptr->val.l >= -4096) && (iptr->val.l <= 4095)) {
927 M_XOR_IMM(s1, iptr->val.l, d);
929 LCONST(REG_ITMP2, iptr->val.l);
930 M_XOR(s1, REG_ITMP2, d);
932 emit_store(jd, iptr, iptr->dst, d);
936 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
938 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
939 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
940 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
943 M_XCMOVLT_IMM(-1, d);
945 emit_store(jd, iptr, iptr->dst, d);
949 case ICMD_IINC: /* ..., value ==> ..., value + constant */
950 /* op1 = variable, val.i = constant */
952 var = &(rd->locals[iptr->op1][TYPE_INT]);
953 if (var->flags & INMEMORY) {
955 M_LDX(s1, REG_SP, var->regoff * 8);
958 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
959 M_ADD_IMM(s1, iptr->val.i, s1);
961 ICONST(REG_ITMP2, iptr->val.i);
962 M_ADD(s1, REG_ITMP2, s1);
964 if (var->flags & INMEMORY)
965 M_STX(s1, REG_SP, var->regoff * 8);
969 /* floating operations ************************************************/
971 case ICMD_FNEG: /* ..., value ==> ..., - value */
973 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
974 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
976 emit_store(jd, iptr, iptr->dst, d);
979 case ICMD_DNEG: /* ..., value ==> ..., - value */
981 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
982 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
984 emit_store(jd, iptr, iptr->dst, d);
987 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
989 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
990 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
991 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
993 emit_store(jd, iptr, iptr->dst, d);
996 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
998 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
999 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1000 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1002 emit_store(jd, iptr, iptr->dst, d);
1005 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1007 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1008 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1009 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1011 emit_store(jd, iptr, iptr->dst, d);
1014 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1016 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1017 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1018 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1020 emit_store(jd, iptr, iptr->dst, d);
1023 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1025 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1026 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1027 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1029 emit_store(jd, iptr, iptr->dst, d);
1032 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1034 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1035 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1036 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1038 emit_store(jd, iptr, iptr->dst, d);
1041 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1043 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1044 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1045 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1047 emit_store(jd, iptr, iptr->dst, d);
1050 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1052 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1053 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1054 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1056 emit_store(jd, iptr, iptr->dst, d);
1060 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1061 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1062 disp = dseg_addfloat(cd, 0.0);
1063 M_IST (s1, REG_PV_CALLEE, disp);
1064 M_FLD (d, REG_PV_CALLEE, disp);
1065 M_CVTIF (d, d); /* rd gets translated to double target register */
1066 emit_store(jd, iptr, iptr->dst, d);
1070 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1071 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1072 disp = dseg_adddouble(cd, 0.0);
1073 M_STX (s1, REG_PV_CALLEE, disp);
1074 M_DLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1075 M_CVTLF (REG_FTMP2, d); /* rd gets translated to double target register */
1076 emit_store(jd, iptr, iptr->dst, d);
1079 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1080 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1081 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1082 disp = dseg_addfloat(cd, 0.0);
1083 M_CVTFI(s1, REG_FTMP2);
1084 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1085 M_ILD(d, REG_PV, disp);
1086 emit_store(jd, iptr, iptr->dst, d);
1090 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1091 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1092 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1093 disp = dseg_addfloat(cd, 0.0);
1094 M_CVTDI(s1, REG_FTMP2);
1095 M_FST(REG_FTMP2, REG_PV, disp);
1096 M_ILD(d, REG_PV, disp);
1097 emit_store(jd, iptr, iptr->dst, d);
1100 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1101 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1102 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1103 disp = dseg_adddouble(cd, 0.0);
1104 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1105 M_DST(REG_FTMP2, REG_PV, disp);
1106 M_LDX(d, REG_PV, disp);
1107 emit_store(jd, iptr, iptr->dst, d);
1110 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1111 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1112 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1113 disp = dseg_adddouble(cd, 0.0);
1114 M_CVTDL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1115 M_DST(REG_FTMP2, REG_PV, disp);
1116 M_LDX(d, REG_PV, disp);
1117 emit_store(jd, iptr, iptr->dst, d);
1120 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1122 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1123 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1125 emit_store(jd, iptr, iptr->dst, d);
1128 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1130 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1131 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1133 emit_store(jd, iptr, iptr->dst, d);
1136 /* XXX merge F/D versions? only compare instr. is different */
1137 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1139 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1140 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1141 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1143 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1144 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1145 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1146 emit_store(jd, iptr, iptr->dst, d);
1149 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1151 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1152 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1153 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1155 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1156 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1157 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1158 emit_store(jd, iptr, iptr->dst, d);
1161 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1163 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1164 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1165 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1167 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1168 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1169 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1170 emit_store(jd, iptr, iptr->dst, d);
1173 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1175 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1176 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1177 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1179 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1180 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1181 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1182 emit_store(jd, iptr, iptr->dst, d);
1186 /* memory operations **************************************************/
1188 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1190 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1191 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1192 gen_nullptr_check(s1);
1193 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1194 emit_store(jd, iptr, iptr->dst, d);
1197 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1199 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1200 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1201 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1202 if (iptr->op1 == 0) {
1203 gen_nullptr_check(s1);
1206 M_AADD(s2, s1, REG_ITMP3);
1207 M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1208 emit_store(jd, iptr, iptr->dst, d);
1211 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1213 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1214 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1215 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1216 if (iptr->op1 == 0) {
1217 gen_nullptr_check(s1);
1220 M_AADD(s2, s1, REG_ITMP3);
1221 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1222 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1223 emit_store(jd, iptr, iptr->dst, d);
1226 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1228 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1229 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1230 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1231 if (iptr->op1 == 0) {
1232 gen_nullptr_check(s1);
1235 M_AADD(s2, s1, REG_ITMP3);
1236 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1237 M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1238 emit_store(jd, iptr, iptr->dst, d);
1241 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1243 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1244 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1245 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1246 if (iptr->op1 == 0) {
1247 gen_nullptr_check(s1);
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(jd, iptr, iptr->dst, d);
1256 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1258 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1259 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1260 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1261 if (iptr->op1 == 0) {
1262 gen_nullptr_check(s1);
1265 M_ASLL_IMM(s2, 3, REG_ITMP3);
1266 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1267 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1268 emit_store(jd, iptr, iptr->dst, d);
1271 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1273 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1274 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1275 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1276 if (iptr->op1 == 0) {
1277 gen_nullptr_check(s1);
1280 M_ASLL_IMM(s2, 2, REG_ITMP3);
1281 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1282 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1283 emit_store(jd, iptr, iptr->dst, d);
1286 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1288 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1289 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1290 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1291 if (iptr->op1 == 0) {
1292 gen_nullptr_check(s1);
1295 M_ASLL_IMM(s2, 3, REG_ITMP3);
1296 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1297 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1298 emit_store(jd, iptr, iptr->dst, d);
1301 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1303 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1304 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1305 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1306 if (iptr->op1 == 0) {
1307 gen_nullptr_check(s1);
1310 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1311 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1312 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1313 emit_store(jd, iptr, iptr->dst, d);
1317 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1319 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1320 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1321 if (iptr->op1 == 0) {
1322 gen_nullptr_check(s1);
1325 M_AADD(s2, s1, REG_ITMP1);
1326 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1327 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1330 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1331 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1333 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1334 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1335 if (iptr->op1 == 0) {
1336 gen_nullptr_check(s1);
1339 M_AADD(s2, s1, REG_ITMP1);
1340 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1341 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1342 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1345 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1347 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1348 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1349 if (iptr->op1 == 0) {
1350 gen_nullptr_check(s1);
1353 M_ASLL_IMM(s2, 2, REG_ITMP2);
1354 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1355 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1356 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1359 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1361 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1362 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1363 if (iptr->op1 == 0) {
1364 gen_nullptr_check(s1);
1367 M_ASLL_IMM(s2, 3, REG_ITMP2);
1368 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1369 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1370 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1373 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1375 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1376 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1377 if (iptr->op1 == 0) {
1378 gen_nullptr_check(s1);
1381 M_ASLL_IMM(s2, 2, REG_ITMP2);
1382 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1383 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1384 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1387 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1389 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1390 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1391 if (iptr->op1 == 0) {
1392 gen_nullptr_check(s1);
1395 M_ASLL_IMM(s2, 3, REG_ITMP2);
1396 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1397 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1398 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1402 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1404 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1405 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1406 if (iptr->op1 == 0) {
1407 gen_nullptr_check(s1);
1410 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1412 M_MOV(s1, rd->argintregs[0]);
1413 M_MOV(s3, rd->argintregs[1]);
1414 disp = dseg_addaddress(cd, BUILTIN_canstore);
1415 M_ALD(REG_ITMP3, REG_PV, disp);
1416 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1419 M_BEQZ(REG_RESULT_CALLER, 0);
1420 codegen_add_arraystoreexception_ref(cd);
1423 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1424 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1425 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1426 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1427 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1428 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1432 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1434 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1435 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1436 if (iptr->op1 == 0) {
1437 gen_nullptr_check(s1);
1440 M_AADD(s2, s1, REG_ITMP1);
1441 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1444 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1445 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1447 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1448 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1449 if (iptr->op1 == 0) {
1450 gen_nullptr_check(s1);
1453 M_AADD(s2, s1, REG_ITMP1);
1454 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1455 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1458 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1460 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1461 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1462 if (iptr->op1 == 0) {
1463 gen_nullptr_check(s1);
1466 M_ASLL_IMM(s2, 2, REG_ITMP2);
1467 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1468 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1471 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1473 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1474 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1475 if (iptr->op1 == 0) {
1476 gen_nullptr_check(s1);
1479 M_ASLL_IMM(s2, 3, REG_ITMP2);
1480 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1481 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1484 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1486 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1487 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1488 if (iptr->op1 == 0) {
1489 gen_nullptr_check(s1);
1492 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1493 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1494 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1498 case ICMD_GETSTATIC: /* ... ==> ..., value */
1499 /* op1 = type, val.a = field address */
1501 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1502 disp = dseg_addaddress(cd, NULL);
1504 codegen_addpatchref(cd, PATCHER_get_putstatic,
1505 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1507 if (opt_showdisassemble) {
1512 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1514 disp = dseg_addaddress(cd, &(fi->value));
1516 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1517 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1519 if (opt_showdisassemble) {
1525 M_ALD(REG_ITMP1, REG_PV, disp);
1526 switch (iptr->op1) {
1528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1529 M_ILD_INTERN(d, REG_ITMP1, 0);
1530 emit_store(jd, iptr, iptr->dst, d);
1533 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1534 M_LDX_INTERN(d, REG_ITMP1, 0);
1535 emit_store(jd, iptr, iptr->dst, d);
1538 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1539 M_ALD_INTERN(d, REG_ITMP1, 0);
1540 emit_store(jd, iptr, iptr->dst, d);
1543 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1544 M_FLD_INTERN(d, REG_ITMP1, 0);
1545 emit_store(jd, iptr, iptr->dst, d);
1548 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1549 M_DLD_INTERN(d, REG_ITMP1, 0);
1550 emit_store(jd, iptr, iptr->dst, d);
1555 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1556 /* op1 = type, val.a = field address */
1558 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1559 disp = dseg_addaddress(cd, NULL);
1561 codegen_addpatchref(cd, PATCHER_get_putstatic,
1562 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1564 if (opt_showdisassemble) {
1569 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1571 disp = dseg_addaddress(cd, &(fi->value));
1573 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1574 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1576 if (opt_showdisassemble) {
1582 M_ALD(REG_ITMP1, REG_PV, disp);
1583 switch (iptr->op1) {
1585 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1586 M_IST_INTERN(s1, REG_ITMP1, 0);
1589 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1590 M_STX_INTERN(s1, REG_ITMP1, 0);
1593 s1 = emit_load_s1(jd, iptr, src, REG_ITMP2);
1594 M_AST_INTERN(s1, REG_ITMP1, 0);
1597 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1598 M_FST_INTERN(s1, REG_ITMP1, 0);
1601 s1 = emit_load_s1(jd, iptr, src, REG_FTMP2);
1602 M_DST_INTERN(s1, REG_ITMP1, 0);
1607 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1608 /* val = value (in current instruction) */
1609 /* op1 = type, val.a = field address (in */
1610 /* following NOP) */
1612 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
1613 disp = dseg_addaddress(cd, NULL);
1615 codegen_addpatchref(cd, PATCHER_get_putstatic,
1616 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
1618 if (opt_showdisassemble) {
1623 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
1625 disp = dseg_addaddress(cd, &(fi->value));
1627 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1628 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1630 if (opt_showdisassemble) {
1636 M_ALD(REG_ITMP1, REG_PV, disp);
1637 switch (iptr->op1) {
1639 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1642 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1645 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1648 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1651 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1657 case ICMD_GETFIELD: /* ... ==> ..., value */
1658 /* op1 = type, val.i = field offset */
1660 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1661 gen_nullptr_check(s1);
1663 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1664 codegen_addpatchref(cd, PATCHER_get_putfield,
1665 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
1667 if (opt_showdisassemble) {
1674 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
1677 switch (iptr->op1) {
1679 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1681 emit_store(jd, iptr, iptr->dst, d);
1684 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1686 emit_store(jd, iptr, iptr->dst, d);
1689 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1691 emit_store(jd, iptr, iptr->dst, d);
1694 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1696 emit_store(jd, iptr, iptr->dst, d);
1699 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1701 emit_store(jd, iptr, iptr->dst, d);
1706 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1707 /* op1 = type, val.a = field address */
1709 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP2);
1710 gen_nullptr_check(s1);
1712 /*if (!IS_FLT_DBL_TYPE(iptr->op1)) {
1713 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1715 s2 = emit_load_s2(jd, iptr, src, REG_IFTMP);
1718 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1719 codegen_addpatchref(cd, PATCHER_get_putfield,
1720 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
1722 if (opt_showdisassemble) {
1729 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
1732 switch (iptr->op1) {
1734 M_IST(s2, s1, disp);
1737 M_STX(s2, s1, disp);
1740 M_AST(s2, s1, disp);
1743 M_FST(s2, s1, disp);
1746 M_DST(s2, s1, disp);
1751 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1752 /* val = value (in current instruction) */
1753 /* op1 = type, val.a = field address (in */
1754 /* following NOP) */
1756 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1757 gen_nullptr_check(s1);
1759 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
1760 codegen_addpatchref(cd, PATCHER_get_putfield,
1761 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
1763 if (opt_showdisassemble) {
1770 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
1773 switch (iptr[1].op1) {
1775 M_IST(REG_ZERO, s1, disp);
1778 M_STX(REG_ZERO, s1, disp);
1781 M_AST(REG_ZERO, s1, disp);
1784 M_FST(REG_ZERO, s1, disp);
1787 M_DST(REG_ZERO, s1, disp);
1793 /* branch operations **************************************************/
1795 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1797 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1798 M_INTMOVE(s1, REG_ITMP2_XPTR);
1800 #ifdef ENABLE_VERIFIER
1802 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1803 (unresolved_class *) iptr->val.a, 0);
1805 if (opt_showdisassemble)
1808 #endif /* ENABLE_VERIFIER */
1810 disp = dseg_addaddress(cd, asm_handle_exception);
1811 M_ALD(REG_ITMP2, REG_PV, disp);
1812 M_JMP(REG_ITMP3_XPC, REG_ITMP2, REG_ZERO);
1814 M_NOP; /* nop ensures that XPC is less than the end */
1815 /* of basic block */
1819 case ICMD_GOTO: /* ... ==> ... */
1820 /* op1 = target JavaVM pc */
1822 codegen_addreference(cd, (basicblock *) iptr->target);
1827 case ICMD_JSR: /* ... ==> ... */
1828 /* op1 = target JavaVM pc */
1830 dseg_addtarget(cd, (basicblock *) iptr->target);
1831 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
1832 M_JMP(REG_ITMP1, REG_ITMP1, REG_ZERO); /* REG_ITMP1 = return address */
1836 case ICMD_RET: /* ... ==> ... */
1837 /* op1 = local variable */
1838 var = &(rd->locals[iptr->op1][TYPE_ADR]);
1839 if (var->flags & INMEMORY) {
1840 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
1848 case ICMD_IFNULL: /* ..., value ==> ... */
1849 /* op1 = target JavaVM pc */
1851 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1853 codegen_addreference(cd, (basicblock *) iptr->target);
1857 case ICMD_IFNONNULL: /* ..., value ==> ... */
1858 /* op1 = target JavaVM pc */
1860 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1862 codegen_addreference(cd, (basicblock *) iptr->target);
1866 case ICMD_IFEQ: /* ..., value ==> ... */
1867 /* op1 = target JavaVM pc, val.i = constant */
1869 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1870 if (iptr->val.i == 0) {
1873 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1874 M_CMP_IMM(s1, iptr->val.i);
1877 ICONST(REG_ITMP2, iptr->val.i);
1878 M_CMP(s1, REG_ITMP2);
1882 codegen_addreference(cd, (basicblock *) iptr->target);
1886 case ICMD_IFLT: /* ..., value ==> ... */
1887 /* op1 = target JavaVM pc, val.i = constant */
1889 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1890 if (iptr->val.i == 0) {
1893 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1894 M_CMP_IMM(s1, iptr->val.i);
1896 ICONST(REG_ITMP2, iptr->val.i);
1897 M_CMP(s1, REG_ITMP2);
1901 codegen_addreference(cd, (basicblock *) iptr->target);
1905 case ICMD_IFLE: /* ..., value ==> ... */
1906 /* op1 = target JavaVM pc, val.i = constant */
1908 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1909 if (iptr->val.i == 0) {
1913 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1914 M_CMP_IMM(s1, iptr->val.i);
1917 ICONST(REG_ITMP2, iptr->val.i);
1918 M_CMP(s1, REG_ITMP2);
1922 codegen_addreference(cd, (basicblock *) iptr->target);
1926 case ICMD_IFNE: /* ..., value ==> ... */
1927 /* op1 = target JavaVM pc, val.i = constant */
1929 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1930 if (iptr->val.i == 0) {
1934 if ((iptr->val.i >= -4096) && (iptr->val.i <= 4095)) {
1935 M_CMP_IMM(s1, iptr->val.i);
1938 ICONST(REG_ITMP2, iptr->val.i);
1939 M_CMP(s1, REG_ITMP2);
1943 codegen_addreference(cd, (basicblock *) iptr->target);
1947 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1948 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
1950 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1951 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1954 codegen_addreference(cd, (basicblock *) iptr->target);
1958 case ICMD_IF_ICMPEQ: /* 32-bit compare */
1960 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1961 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1964 codegen_addreference(cd, (basicblock *) iptr->target);
1968 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1969 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
1971 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1972 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1975 codegen_addreference(cd, (basicblock *) iptr->target);
1979 case ICMD_IF_ICMPNE: /* 32-bit compare */
1981 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1982 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1985 codegen_addreference(cd, (basicblock *) iptr->target);
1989 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1990 /* op1 = target JavaVM pc */
1992 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1993 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1996 codegen_addreference(cd, (basicblock *) iptr->target);
2000 case ICMD_IF_ICMPLT: /* 32-bit compare */
2002 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2003 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2006 codegen_addreference(cd, (basicblock *) iptr->target);
2010 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2011 /* op1 = target JavaVM pc */
2013 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2014 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2017 codegen_addreference(cd, (basicblock *) iptr->target);
2021 case ICMD_IF_ICMPGT: /* 32-bit compare */
2023 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2024 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2027 codegen_addreference(cd, (basicblock *) iptr->target);
2031 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2032 /* op1 = target JavaVM pc */
2034 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2035 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2038 codegen_addreference(cd, (basicblock *) iptr->target);
2042 case ICMD_IF_ICMPLE: /* 32-bit compare */
2044 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2045 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2048 codegen_addreference(cd, (basicblock *) iptr->target);
2053 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2054 /* op1 = target JavaVM pc */
2056 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2057 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2060 codegen_addreference(cd, (basicblock *) iptr->target);
2064 case ICMD_IF_ICMPGE: /* 32-bit compare */
2066 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2067 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2070 codegen_addreference(cd, (basicblock *) iptr->target);
2075 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2078 s1 = emit_load_s1(jd, iptr, src, REG_RESULT_CALLEE);
2079 M_INTMOVE(s1, REG_RESULT_CALLEE);
2080 goto nowperformreturn;
2082 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2084 s1 = emit_load_s1(jd, iptr, src, REG_RESULT_CALLEE);
2085 M_INTMOVE(s1, REG_RESULT_CALLEE);
2087 #ifdef ENABLE_VERIFIER
2089 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2090 (unresolved_class *) iptr->val.a, 0);
2092 if (opt_showdisassemble)
2095 #endif /* ENABLE_VERIFIER */
2096 goto nowperformreturn;
2098 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2101 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2102 M_FLTMOVE(s1, REG_FRESULT);
2103 goto nowperformreturn;
2105 case ICMD_RETURN: /* ... ==> ... */
2113 /* call trace function */
2115 #if !defined(NDEBUG)
2116 if (opt_verbosecall) {
2117 M_LDA(REG_SP, REG_SP, -3 * 8);
2118 M_AST(REG_RA_CALLEE, REG_SP, 0 * 8); /* XXX: no need to save anything but FRES ? */
2119 /* M_STX(REG_RESULT, REG_SP, 1 * 8); */
2120 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2122 disp = dseg_addaddress(cd, m);
2123 M_ALD(rd->argintregs[0], REG_PV, disp);
2124 M_MOV(REG_RESULT_CALLEE, rd->argintregs[1]);
2125 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2126 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2128 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2129 M_ALD(REG_ITMP3, REG_PV, disp);
2130 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2133 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2134 /* M_LDX(REG_RESULT, REG_SP, 1 * 8); */
2135 M_ALD(REG_RA_CALLEE, REG_SP, 0 * 8);
2136 M_LDA(REG_SP, REG_SP, 3 * 8);
2140 #if defined(ENABLE_THREADS)
2141 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2142 /* XXX: REG_RESULT is save, but what about FRESULT? */
2143 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2145 switch (iptr->opc) {
2148 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2152 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2153 M_ALD(REG_ITMP3, REG_PV, disp);
2154 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2156 switch (iptr->opc) {
2159 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2167 M_RETURN(REG_RA_CALLEE); /* implicit window restore */
2175 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2180 } /* for instruction */
2183 /* copy values to interface registers */
2185 src = bptr->outstack;
2186 len = bptr->outdepth;
2188 #if defined(ENABLE_LSRA)
2193 if ((src->varkind != STACKVAR)) {
2195 if (IS_FLT_DBL_TYPE(s2)) {
2196 var_to_reg_flt(s1, src, REG_FTMP1);
2197 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2198 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
2201 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
2205 var_to_reg_int(s1, src, REG_ITMP1);
2206 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
2207 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
2210 M_STX(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
2216 } /* if (bptr -> flags >= BBREACHED) */
2217 } /* for basic block */
2227 /* createcompilerstub **********************************************************
2229 Creates a stub routine which calls the compiler.
2231 *******************************************************************************/
2233 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
2234 #define COMPILERSTUB_CODESIZE 3 * 4
2236 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2239 u1 *createcompilerstub(methodinfo *m)
2241 u1 *s; /* memory to hold the stub */
2243 s4 *mcodeptr; /* code generation pointer */
2245 s = CNEW(u1, COMPILERSTUB_SIZE);
2247 /* set data pointer and code pointer */
2250 s = s + COMPILERSTUB_DATASIZE;
2252 mcodeptr = (s4 *) s;
2254 /* Store the methodinfo* in the same place as in the methodheader
2255 for compiled methods. */
2257 d[0] = (ptrint) asm_call_jit_compiler;
2260 /* code for the stub */
2262 M_LDX(REG_ITMP1, REG_PV_CALLER, -1 * 8); /* load methodinfo pointer */
2263 /* XXX CALLER PV ??? */
2264 M_LDX(REG_PV_CALLER ,REG_PV_CALLER, -2 * 8); /* load pointer to the compiler */
2265 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2267 #if defined(ENABLE_STATISTICS)
2269 count_cstub_len += COMPILERSTUB_SIZE;
2277 /* createnativestub ************************************************************
2279 Creates a stub routine which calls a native method.
2281 *******************************************************************************/
2283 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2290 * These are local overrides for various environment variables in Emacs.
2291 * Please do not remove this and leave it at the end of the file, where
2292 * Emacs will automagically detect them.
2293 * ---------------------------------------------------------------------
2296 * indent-tabs-mode: t
2300 * vim:noexpandtab:sw=4:ts=4: