1 /* src/vm/jit/sparc64/codegen.c - machine code generator for Sparc
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
31 Changes: Edwin Steiner
33 $Id: codegen.c 4644 2006-03-16 18:44:46Z edwin $
48 /* #include "vm/jit/sparc64/arch.h" */
49 #include "vm/jit/sparc64/codegen.h"
51 #include "mm/memory.h"
53 #include "native/jni.h"
54 #include "native/native.h"
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/codegen-common.h"
63 #include "vm/jit/dseg.h"
64 #include "vm/jit/emit-common.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/parse.h"
67 #include "vm/jit/patcher.h"
68 #include "vm/jit/reg.h"
70 /* XXX use something like this for window control ?
71 * #define REG_PV (own_window?REG_PV_CALLEE:REG_PV_CALLER)
73 #define REG_PV REG_PV_CALLEE
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;
101 rplpoint *replacementpoint;
105 /* get required compiler data */
112 /* prevent compiler warnings */
121 s4 savedregs_num, localbase;
123 #if 0 /* no leaf optimization yet */
124 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
126 savedregs_num = 16; /* register-window save area */
129 /* space to save used callee saved registers */
131 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
132 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
134 cd->stackframesize = rd->memuse + savedregs_num;
136 #if defined(ENABLE_THREADS) /* space to save argument of monitor_enter */
137 if (checksync && (m->flags & ACC_SYNCHRONIZED))
138 cd->stackframesize++;
141 /* create method header */
143 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
144 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
146 #if defined(ENABLE_THREADS)
147 /* IsSync contains the offset relative to the stack pointer for the
148 argument of monitor_exit used in the exception handler. Since the
149 offset could be zero and give a wrong meaning of the flag it is
153 if (checksync && (m->flags & ACC_SYNCHRONIZED))
154 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
157 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
159 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
160 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
161 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
162 dseg_addlinenumbertablesize(cd);
163 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
165 /* create exception table */
167 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
168 dseg_add_target(cd, ex->start);
169 dseg_add_target(cd, ex->end);
170 dseg_add_target(cd, ex->handler);
171 (void) dseg_add_unique_address(cd, ex->catchtype.any);
174 /* save register window and create stack frame (if necessary) */
176 if (cd->stackframesize)
177 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP);
180 /* save callee saved float registers (none right now) */
182 p = cd->stackframesize;
183 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
184 p--; M_DST(rd->savfltregs[i], REG_SP, USESTACK + (p * 8));
189 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
190 emit_verbosecall_enter(jd);
195 /* take arguments out of register or stack frame */
199 /* when storing locals, use this as base */
200 localbase = USESTACK;
202 /* since the register allocator does not know about the shifting window
203 * arg regs need to be copied via the stack
205 if (md->argintreguse > 0) {
206 /* allocate scratch space for copying in to save(i&l) regs */
207 M_SUB_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
209 localbase += INT_ARG_CNT * 8;
211 for (p = 0; p < INT_ARG_CNT; p++)
212 M_STX(REG_WINDOW_TRANSPOSE(rd->argintregs[p]), REG_SP, USESTACK + (p * 8));
216 for (p = 0, l = 0; p < md->paramcount; p++) {
217 t = md->paramtypes[p].type;
219 varindex = jd->local_map[l * 5 + t];
222 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
225 if (varindex == UNUSED)
230 s1 = md->params[p].regoff;
231 if (IS_INT_LNG_TYPE(t)) { /* integer args */
232 if (!md->params[p].inmemory) { /* register arguments */
233 /*s2 = rd->argintregs[s1];*/
234 /*s2 = REG_WINDOW_TRANSPOSE(s2);*/
235 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
236 /*M_INTMOVE(s2, var->vv.regoff);*/
237 M_LDX(var->vv.regoff, REG_SP, USESTACK + (s1 * 8));
239 } else { /* reg arg -> spilled */
240 /*M_STX(s2, REG_SP, (WINSAVE_CNT + var->vv.regoff) * 8);*/
242 M_LDX(REG_ITMP1, REG_SP, USESTACK + (s1 * 8));
243 M_STX(REG_ITMP1, REG_SP, localbase + (var->vv.regoff * 8));
246 } else { /* stack arguments */
247 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
248 M_LDX(var->vv.regoff, REG_FP, (WINSAVE_CNT + s1) * 8);
250 } else { /* stack arg -> spilled */
251 assert(0); /* XXX winsave area in between */
252 var->vv.regoff = cd->stackframesize + s1;
256 } else { /* floating args */
257 if (!md->params[p].inmemory) { /* register arguments */
258 s2 = rd->argfltregs[s1];
259 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
260 M_FLTMOVE(s2, var->vv.regoff);
262 } else { /* reg arg -> spilled */
263 M_DST(s2, REG_SP, localbase + (var->vv.regoff) * 8);
266 } else { /* stack arguments */
267 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
268 M_DLD(var->vv.regoff, REG_FP, (WINSAVE_CNT + s1) * 8);
270 } else { /* stack-arg -> spilled */
271 assert(0); /* XXX winsave area in between */
272 var->vv.regoff = cd->stackframesize + s1;
278 if (md->argintreguse > 0) {
279 /* release scratch space */
280 M_ADD_IMM(REG_SP, INT_ARG_CNT * 8, REG_SP);
284 /* XXX monitor enter */
291 /* end of header generation */
293 replacementpoint = jd->code->rplpoints;
295 /* walk through all basic blocks */
297 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
299 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
301 if (bptr->flags >= BBREACHED) {
303 /* branch resolving */
305 codegen_resolve_branchrefs(cd, bptr);
307 /* handle replacement points */
310 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
311 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
317 /* copy interface registers to their destination */
322 #if defined(ENABLE_LSRA)
326 src = bptr->invars[len];
327 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
328 /* d = reg_of_var(m, src, REG_ITMP1); */
329 if (!(src->flags & INMEMORY))
333 M_INTMOVE(REG_ITMP1, d);
334 emit_store(jd, NULL, src, d);
341 var = VAR(bptr->invars[len]);
342 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
343 d = codegen_reg_of_var(0, var, REG_ITMP1);
344 M_INTMOVE(REG_ITMP1, d);
345 emit_store(jd, NULL, var, d);
348 assert((var->flags & INOUT));
351 #if defined(ENABLE_LSRA)
354 /* walk through all instructions */
358 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
359 if (iptr->line != currentline) {
360 dseg_addlinenumber(cd, iptr->line);
361 currentline = iptr->line;
364 MCODECHECK(64); /* an instruction usually needs < 64 words */
367 case ICMD_INLINE_START:
368 case ICMD_INLINE_END:
371 case ICMD_NOP: /* ... ==> ... */
374 /* constant operations ************************************************/
376 case ICMD_ICONST: /* ... ==> ..., constant */
378 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
379 ICONST(d, iptr->sx.val.i);
380 emit_store_dst(jd, iptr, d);
383 case ICMD_LCONST: /* ... ==> ..., constant */
385 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
386 LCONST(d, iptr->sx.val.l);
387 emit_store_dst(jd, iptr, d);
390 case ICMD_FCONST: /* ... ==> ..., constant */
392 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
393 disp = dseg_add_float(cd, iptr->sx.val.f);
394 M_FLD(d, REG_PV, disp);
395 emit_store_dst(jd, iptr, d);
398 case ICMD_DCONST: /* ... ==> ..., constant */
400 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
401 disp = dseg_add_double(cd, iptr->sx.val.d);
402 M_DLD(d, REG_PV, disp);
403 emit_store_dst(jd, iptr, d);
406 case ICMD_ACONST: /* ... ==> ..., constant */
408 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
410 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
411 cr = iptr->sx.val.c.ref;
412 disp = dseg_add_unique_address(cd, cr);
414 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
416 M_ALD(d, REG_PV, disp);
420 if (iptr->sx.val.anyptr == NULL) {
421 M_INTMOVE(REG_ZERO, d);
424 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
425 M_ALD(d, REG_PV, disp);
428 emit_store_dst(jd, iptr, d);
432 /* load/store/copy/move operations ************************************/
434 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
435 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
436 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
437 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
438 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
439 case ICMD_ISTORE: /* ..., value ==> ... */
440 case ICMD_LSTORE: /* ..., value ==> ... */
441 case ICMD_FSTORE: /* ..., value ==> ... */
442 case ICMD_DSTORE: /* ..., value ==> ... */
446 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
450 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
451 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
455 /* pop/dup/swap operations ********************************************/
457 /* attention: double and longs are only one entry in CACAO ICMDs */
459 case ICMD_POP: /* ..., value ==> ... */
460 case ICMD_POP2: /* ..., value, value ==> ... */
464 /* integer operations *************************************************/
466 case ICMD_INEG: /* ..., value ==> ..., - value */
469 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
470 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
471 M_SUB(REG_ZERO, s1, d);
472 emit_store_dst(jd, iptr, d);
475 case ICMD_I2L: /* ..., value ==> ..., value */
477 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
478 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
480 emit_store_dst(jd, iptr, d);
483 case ICMD_L2I: /* ..., value ==> ..., value */
485 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
486 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
487 M_SRA_IMM(s1, 0, d); /* sign extend upper 32 bits */
488 emit_store_dst(jd, iptr, d);
491 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
494 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
495 M_SLLX_IMM(s1, 56, d);
496 M_SRAX_IMM( d, 56, d);
497 emit_store_dst(jd, iptr, d);
500 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
504 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
505 M_SLLX_IMM(s1, 48, d);
506 M_SRAX_IMM( d, 48, d);
507 emit_store_dst(jd, iptr, d);
510 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
514 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
515 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
517 emit_store_dst(jd, iptr, d);
521 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
522 /* sx.val.i = constant */
524 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
525 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
526 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
527 M_ADD_IMM(s1, iptr->sx.val.i, d);
529 ICONST(REG_ITMP2, iptr->sx.val.i);
530 M_ADD(s1, REG_ITMP2, d);
532 emit_store_dst(jd, iptr, d);
535 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
536 /* sx.val.l = constant */
538 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
539 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
540 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
541 M_ADD_IMM(s1, iptr->sx.val.l, d);
543 LCONST(REG_ITMP2, iptr->sx.val.l);
544 M_ADD(s1, REG_ITMP2, d);
546 emit_store_dst(jd, iptr, d);
549 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
552 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
553 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
554 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
556 emit_store_dst(jd, iptr, d);
559 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
560 /* sx.val.i = constant */
562 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
564 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
565 M_SUB_IMM(s1, iptr->sx.val.i, d);
567 ICONST(REG_ITMP2, iptr->sx.val.i);
568 M_SUB(s1, REG_ITMP2, d);
570 emit_store_dst(jd, iptr, d);
573 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
574 /* sx.val.l = constant */
576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
577 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
578 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
579 M_SUB_IMM(s1, iptr->sx.val.l, d);
581 LCONST(REG_ITMP2, iptr->sx.val.l);
582 M_SUB(s1, REG_ITMP2, d);
584 emit_store_dst(jd, iptr, d);
587 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
591 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
592 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
594 emit_store_dst(jd, iptr, d);
597 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
598 /* sx.val.i = constant */
600 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
601 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
602 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
603 M_MULX_IMM(s1, iptr->sx.val.i, d);
605 ICONST(REG_ITMP2, iptr->sx.val.i);
606 M_MULX(s1, REG_ITMP2, d);
608 emit_store_dst(jd, iptr, d);
611 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
612 /* sx.val.l = constant */
614 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
615 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
616 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
617 M_MULX_IMM(s1, iptr->sx.val.l, d);
619 LCONST(REG_ITMP2, iptr->sx.val.l);
620 M_MULX(s1, REG_ITMP2, d);
622 emit_store_dst(jd, iptr, d);
625 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
626 /* XXX could also clear Y and use 32bit div */
627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
628 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
632 /* XXX trim s2 like s1 ? */
634 emit_store_dst(jd, iptr, d);
637 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
641 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
644 emit_store_dst(jd, iptr, d);
647 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
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_ITMP3);
654 /* XXX trim s2 like s1 ? */
658 emit_store_dst(jd, iptr, d);
661 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
663 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
664 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
665 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
670 emit_store_dst(jd, iptr, d);
673 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
674 case ICMD_LDIVPOW2: /* val.i = constant */
676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
678 M_SRAX_IMM(s1, 63, REG_ITMP2);
679 M_SRLX_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
680 M_ADD(s1, REG_ITMP2, REG_ITMP2);
681 M_SRAX_IMM(REG_ITMP2, iptr->sx.val.i, d);
682 emit_store_dst(jd, iptr, d);
685 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
688 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
689 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
690 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
692 emit_store_dst(jd, iptr, d);
695 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
696 case ICMD_LSHLCONST: /* val.i = constant */
698 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
700 M_SLLX_IMM(s1, iptr->sx.val.i, d);
701 emit_store_dst(jd, iptr, d);
704 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
706 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
707 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
708 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
710 emit_store_dst(jd, iptr, d);
713 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
714 /* sx.val.i = constant */
716 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
717 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
718 M_SRA_IMM(s1, iptr->sx.val.i, d);
719 emit_store_dst(jd, iptr, d);
722 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
725 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
728 emit_store_dst(jd, iptr, d);
731 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
732 /* sx.val.i = constant */
734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
735 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
736 M_SRL_IMM(s1, iptr->sx.val.i, d);
737 emit_store_dst(jd, iptr, d);
740 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
742 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
743 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
744 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
746 emit_store_dst(jd, iptr, d);
749 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
750 /* sx.val.i = constant */
752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
754 M_SRAX_IMM(s1, iptr->sx.val.i, d);
755 emit_store_dst(jd, iptr, d);
758 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
760 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
761 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
764 emit_store_dst(jd, iptr, d);
767 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
768 /* sx.val.i = constant */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772 M_SRLX_IMM(s1, iptr->sx.val.i, d);
773 emit_store_dst(jd, iptr, d);
776 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
779 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
780 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
783 emit_store_dst(jd, iptr, d);
786 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
787 /* sx.val.i = constant */
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
792 M_AND_IMM(s1, iptr->sx.val.i, d);
794 ICONST(REG_ITMP2, iptr->sx.val.i);
795 M_AND(s1, REG_ITMP2, d);
797 emit_store_dst(jd, iptr, d);
800 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
801 /* sx.val.i = constant */
803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
805 M_ISEXT(s1, s1); /* trim for 32-bit compare (BGEZ) */
807 M_MOV(s1, REG_ITMP1);
810 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
811 M_AND_IMM(s1, iptr->sx.val.i, d);
814 M_SUB(REG_ZERO, s1, d);
815 M_AND_IMM(d, iptr->sx.val.i, d);
817 ICONST(REG_ITMP2, iptr->sx.val.i);
818 M_AND(s1, REG_ITMP2, d);
821 M_SUB(REG_ZERO, s1, d);
822 M_AND(d, REG_ITMP2, d);
824 M_SUB(REG_ZERO, d, d);
825 emit_store_dst(jd, iptr, d);
828 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
829 /* sx.val.l = constant */
831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
832 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
833 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
834 M_AND_IMM(s1, iptr->sx.val.l, d);
836 LCONST(REG_ITMP2, iptr->sx.val.l);
837 M_AND(s1, REG_ITMP2, d);
839 emit_store_dst(jd, iptr, d);
842 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
843 /* sx.val.l = constant */
845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
846 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
848 M_MOV(s1, REG_ITMP1);
851 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
852 M_AND_IMM(s1, iptr->sx.val.l, d);
855 M_SUB(REG_ZERO, s1, d);
856 M_AND_IMM(d, iptr->sx.val.l, d);
858 LCONST(REG_ITMP2, iptr->sx.val.l);
859 M_AND(s1, REG_ITMP2, d);
862 M_SUB(REG_ZERO, s1, d);
863 M_AND(d, REG_ITMP2, d);
865 M_SUB(REG_ZERO, d, d);
866 emit_store_dst(jd, iptr, d);
869 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
873 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
874 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
876 emit_store_dst(jd, iptr, d);
879 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
880 /* sx.val.i = constant */
882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
883 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
884 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
885 M_OR_IMM(s1, iptr->sx.val.i, d);
887 ICONST(REG_ITMP2, iptr->sx.val.i);
888 M_OR(s1, REG_ITMP2, d);
890 emit_store_dst(jd, iptr, d);
893 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
894 /* sx.val.l = constant */
896 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
897 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
899 M_OR_IMM(s1, iptr->sx.val.l, d);
901 LCONST(REG_ITMP2, iptr->sx.val.l);
902 M_OR(s1, REG_ITMP2, d);
904 emit_store_dst(jd, iptr, d);
907 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
912 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
914 emit_store_dst(jd, iptr, d);
917 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
918 /* sx.val.i = constant */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
922 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
923 M_XOR_IMM(s1, iptr->sx.val.i, d);
925 ICONST(REG_ITMP2, iptr->sx.val.i);
926 M_XOR(s1, REG_ITMP2, d);
928 emit_store_dst(jd, iptr, d);
931 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
932 /* sx.val.l = constant */
934 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
935 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
936 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
937 M_XOR_IMM(s1, iptr->sx.val.l, d);
939 LCONST(REG_ITMP2, iptr->sx.val.l);
940 M_XOR(s1, REG_ITMP2, d);
942 emit_store_dst(jd, iptr, d);
946 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
953 M_XCMOVLT_IMM(-1, d);
955 emit_store_dst(jd, iptr, d);
959 /* floating operations ************************************************/
961 case ICMD_FNEG: /* ..., value ==> ..., - value */
963 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
964 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
966 emit_store_dst(jd, iptr, d);
969 case ICMD_DNEG: /* ..., value ==> ..., - value */
971 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
972 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
974 emit_store_dst(jd, iptr, d);
977 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
979 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
980 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
981 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
983 emit_store_dst(jd, iptr, d);
986 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
988 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
989 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
990 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
992 emit_store_dst(jd, iptr, d);
995 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
997 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
998 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
999 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1001 emit_store_dst(jd, iptr, d);
1004 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1006 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1007 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1008 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1010 emit_store_dst(jd, iptr, d);
1013 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1015 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1016 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1017 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1019 emit_store_dst(jd, iptr, d);
1022 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1024 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1025 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1026 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1028 emit_store_dst(jd, iptr, d);
1031 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1033 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1034 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1035 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1037 emit_store_dst(jd, iptr, d);
1040 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1042 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1043 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1044 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1046 emit_store_dst(jd, iptr, d);
1050 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1051 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1052 disp = dseg_add_float(cd, 0.0);
1053 M_IST (s1, REG_PV_CALLEE, disp);
1054 M_FLD (d, REG_PV_CALLEE, disp);
1055 M_CVTIF (d, d); /* rd gets translated to double target register */
1056 emit_store_dst(jd, iptr, d);
1060 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1061 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1062 disp = dseg_add_float(cd, 0.0);
1063 M_IST (s1, REG_PV_CALLEE, disp);
1064 M_FLD (REG_FTMP2, REG_PV_CALLEE, disp); /* REG_FTMP2 needs to be a double temp */
1065 M_CVTID (REG_FTMP2, d); /* rd gets translated to double target register */
1066 emit_store_dst(jd, iptr, d);
1069 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1070 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1071 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1072 disp = dseg_add_float(cd, 0.0);
1073 M_CVTFI(s1, REG_FTMP2);
1074 M_FST(REG_FTMP2, REG_PV_CALLEE, disp);
1075 M_ILD(d, REG_PV, disp);
1076 emit_store_dst(jd, iptr, d);
1080 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1081 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1082 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1083 disp = dseg_add_float(cd, 0.0);
1084 M_CVTDI(s1, REG_FTMP2);
1085 M_FST(REG_FTMP2, REG_PV, disp);
1086 M_ILD(d, REG_PV, disp);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1091 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1092 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1093 disp = dseg_add_double(cd, 0.0);
1094 M_CVTFL(s1, REG_FTMP2); /* FTMP2 needs to be double reg */
1095 M_DST(REG_FTMP2, REG_PV, disp);
1096 M_LDX(d, REG_PV, disp);
1097 emit_store_dst(jd, iptr, d);
1100 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1101 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1102 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1103 disp = dseg_add_double(cd, 0.0);
1104 M_CVTDL(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_dst(jd, iptr, d);
1110 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1112 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1113 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1115 emit_store_dst(jd, iptr, d);
1118 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1120 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1121 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1123 emit_store_dst(jd, iptr, d);
1126 /* XXX merge F/D versions? only compare instr. is different */
1127 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1129 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1130 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1133 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1134 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1135 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1136 emit_store_dst(jd, iptr, d);
1139 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1141 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1142 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1143 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1145 M_OR_IMM(REG_ZERO, -1, REG_ITMP3); /* less by default (less or unordered) */
1146 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1147 M_CMOVFGT_IMM(1, REG_ITMP3); /* 1 if greater */
1148 emit_store_dst(jd, iptr, d);
1151 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1153 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1154 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1155 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1157 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1158 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1159 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1160 emit_store_dst(jd, iptr, d);
1163 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1165 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1166 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1167 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1169 M_OR_IMM(REG_ZERO, 1, REG_ITMP3); /* greater by default (greater or unordered) */
1170 M_CMOVFEQ_IMM(0, REG_ITMP3); /* 0 if equal */
1171 M_CMOVFLT_IMM(-1, REG_ITMP3); /* -1 if less */
1172 emit_store_dst(jd, iptr, d);
1176 /* memory operations **************************************************/
1178 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1180 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1181 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1182 gen_nullptr_check(s1);
1183 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1184 emit_store_dst(jd, iptr, d);
1187 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1190 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1191 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1192 if (INSTRUCTION_MUST_CHECK(iptr)) {
1193 gen_nullptr_check(s1);
1196 M_AADD(s2, s1, REG_ITMP3);
1197 M_BLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1198 emit_store_dst(jd, iptr, d);
1201 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1203 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1204 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1205 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1206 if (INSTRUCTION_MUST_CHECK(iptr)) {
1207 gen_nullptr_check(s1);
1210 M_AADD(s2, s1, REG_ITMP3);
1211 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1212 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1221 if (INSTRUCTION_MUST_CHECK(iptr)) {
1222 gen_nullptr_check(s1);
1225 M_AADD(s2, s1, REG_ITMP3);
1226 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1227 M_SLDS(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1233 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1234 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1236 if (INSTRUCTION_MUST_CHECK(iptr)) {
1237 gen_nullptr_check(s1);
1240 M_ASLL_IMM(s2, 2, REG_ITMP3);
1241 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1242 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1243 emit_store_dst(jd, iptr, d);
1246 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1248 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1249 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1250 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1251 if (INSTRUCTION_MUST_CHECK(iptr)) {
1252 gen_nullptr_check(s1);
1255 M_ASLL_IMM(s2, 3, REG_ITMP3);
1256 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1257 M_LDX(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1258 emit_store_dst(jd, iptr, d);
1261 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1263 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1264 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1265 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1266 if (INSTRUCTION_MUST_CHECK(iptr)) {
1267 gen_nullptr_check(s1);
1270 M_ASLL_IMM(s2, 2, REG_ITMP3);
1271 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1272 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1273 emit_store_dst(jd, iptr, d);
1276 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1278 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1279 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1280 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1281 if (INSTRUCTION_MUST_CHECK(iptr)) {
1282 gen_nullptr_check(s1);
1285 M_ASLL_IMM(s2, 3, REG_ITMP3);
1286 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1287 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1288 emit_store_dst(jd, iptr, d);
1291 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1293 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1294 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1295 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1296 if (INSTRUCTION_MUST_CHECK(iptr)) {
1297 gen_nullptr_check(s1);
1300 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1301 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1302 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1303 emit_store_dst(jd, iptr, d);
1307 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1309 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1310 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1311 if (INSTRUCTION_MUST_CHECK(iptr)) {
1312 gen_nullptr_check(s1);
1315 M_AADD(s2, s1, REG_ITMP1);
1316 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1317 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1320 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1321 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1325 if (INSTRUCTION_MUST_CHECK(iptr)) {
1326 gen_nullptr_check(s1);
1329 M_AADD(s2, s1, REG_ITMP1);
1330 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1331 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1332 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1335 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1338 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1339 if (INSTRUCTION_MUST_CHECK(iptr)) {
1340 gen_nullptr_check(s1);
1343 M_ASLL_IMM(s2, 2, REG_ITMP2);
1344 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1345 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1346 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1349 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 if (INSTRUCTION_MUST_CHECK(iptr)) {
1354 gen_nullptr_check(s1);
1357 M_ASLL_IMM(s2, 3, REG_ITMP2);
1358 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1359 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1360 M_STX_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1363 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1365 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1366 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1367 if (INSTRUCTION_MUST_CHECK(iptr)) {
1368 gen_nullptr_check(s1);
1371 M_ASLL_IMM(s2, 2, REG_ITMP2);
1372 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1373 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1374 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1377 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1379 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1380 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1381 if (INSTRUCTION_MUST_CHECK(iptr)) {
1382 gen_nullptr_check(s1);
1385 M_ASLL_IMM(s2, 3, REG_ITMP2);
1386 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1387 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1388 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1392 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1395 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1396 if (INSTRUCTION_MUST_CHECK(iptr)) {
1397 gen_nullptr_check(s1);
1400 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1402 M_MOV(s1, rd->argintregs[0]);
1403 M_MOV(s3, rd->argintregs[1]);
1404 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1405 M_ALD(REG_ITMP3, REG_PV, disp);
1406 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
1409 M_BEQZ(REG_RESULT_CALLER, 0);
1410 codegen_add_arraystoreexception_ref(cd);
1413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1415 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1416 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1417 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1418 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1422 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1424 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1425 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1426 if (INSTRUCTION_MUST_CHECK(iptr)) {
1427 gen_nullptr_check(s1);
1430 M_AADD(s2, s1, REG_ITMP1);
1431 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1434 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1435 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1437 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1438 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1439 if (INSTRUCTION_MUST_CHECK(iptr)) {
1440 gen_nullptr_check(s1);
1443 M_AADD(s2, s1, REG_ITMP1);
1444 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1445 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1448 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1451 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1452 if (INSTRUCTION_MUST_CHECK(iptr)) {
1453 gen_nullptr_check(s1);
1456 M_ASLL_IMM(s2, 2, REG_ITMP2);
1457 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1458 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1461 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1463 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1464 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1465 if (INSTRUCTION_MUST_CHECK(iptr)) {
1466 gen_nullptr_check(s1);
1469 M_ASLL_IMM(s2, 3, REG_ITMP2);
1470 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1471 M_STX_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1474 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1476 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1477 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1478 if (INSTRUCTION_MUST_CHECK(iptr)) {
1479 gen_nullptr_check(s1);
1482 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1483 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1484 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1488 case ICMD_GETSTATIC: /* ... ==> ..., value */
1490 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1491 uf = iptr->sx.s23.s3.uf;
1492 fieldtype = uf->fieldref->parseddesc.fd->type;
1493 disp = dseg_add_unique_address(cd, uf);
1495 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1498 fi = iptr->sx.s23.s3.fmiref->p.field;
1499 fieldtype = fi->type;
1500 disp = dseg_add_address(cd, &(fi->value));
1502 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1503 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1506 M_ALD(REG_ITMP1, REG_PV, disp);
1508 switch (fieldtype) {
1510 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1511 M_ILD_INTERN(d, REG_ITMP1, 0);
1514 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1515 M_LDX_INTERN(d, REG_ITMP1, 0);
1518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1519 M_ALD_INTERN(d, REG_ITMP1, 0);
1522 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1523 M_FLD_INTERN(d, REG_ITMP1, 0);
1526 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1527 M_DLD_INTERN(d, REG_ITMP1, 0);
1530 emit_store_dst(jd, iptr, d);
1533 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1535 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1536 uf = iptr->sx.s23.s3.uf;
1537 fieldtype = uf->fieldref->parseddesc.fd->type;
1538 disp = dseg_add_unique_address(cd, uf);
1540 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1543 fi = iptr->sx.s23.s3.fmiref->p.field;
1544 fieldtype = fi->type;
1545 disp = dseg_add_address(cd, &(fi->value));
1547 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1548 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1551 M_ALD(REG_ITMP1, REG_PV, disp);
1553 switch (fieldtype) {
1555 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1556 M_IST_INTERN(s1, REG_ITMP1, 0);
1559 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1560 M_STX_INTERN(s1, REG_ITMP1, 0);
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
1564 M_AST_INTERN(s1, REG_ITMP1, 0);
1567 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1568 M_FST_INTERN(s1, REG_ITMP1, 0);
1571 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
1572 M_DST_INTERN(s1, REG_ITMP1, 0);
1577 case ICMD_PUTSTATICCONST: /* ... ==> ... */
1578 /* val = value (in current instruction) */
1579 /* following NOP) */
1581 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1582 unresolved_field *uf = iptr->sx.s23.s3.uf;
1583 fieldtype = uf->fieldref->parseddesc.fd->type;
1584 disp = dseg_add_unique_address(cd, uf);
1586 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
1589 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1590 fieldtype = fi->type;
1591 disp = dseg_add_address(cd, &(fi->value));
1593 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1594 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
1597 M_ALD(REG_ITMP1, REG_PV, disp);
1599 switch (fieldtype) {
1601 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
1604 M_STX_INTERN(REG_ZERO, REG_ITMP1, 0);
1607 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
1610 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
1613 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
1619 case ICMD_GETFIELD: /* ... ==> ..., value */
1621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1622 gen_nullptr_check(s1);
1624 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1625 uf = iptr->sx.s23.s3.uf;
1627 fieldtype = uf->fieldref->parseddesc.fd->type;
1630 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1633 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1634 fieldtype = fi->type;
1638 switch (fieldtype) {
1640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1648 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1652 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1656 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1663 emit_store_dst(jd, iptr, d);
1666 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1668 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1669 gen_nullptr_check(s1);
1671 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1672 uf = iptr->sx.s23.s3.uf;
1673 fieldtype = uf->fieldref->parseddesc.fd->type;
1678 fi = iptr->sx.s23.s3.fmiref->p.field;
1679 fieldtype = fi->type;
1683 if (IS_INT_LNG_TYPE(fieldtype))
1684 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1686 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1688 if (INSTRUCTION_IS_UNRESOLVED(iptr))
1689 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
1691 switch (fieldtype) {
1693 M_IST(s2, s1, disp);
1696 M_STX(s2, s1, disp);
1699 M_AST(s2, s1, disp);
1702 M_FST(s2, s1, disp);
1705 M_DST(s2, s1, disp);
1713 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
1714 /* val = value (in current instruction) */
1715 /* following NOP) */
1717 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1718 gen_nullptr_check(s1);
1720 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1721 unresolved_field *uf = iptr->sx.s23.s3.uf;
1723 fieldtype = uf->fieldref->parseddesc.fd->type;
1725 codegen_addpatchref(cd, PATCHER_get_putfield,
1728 if (opt_showdisassemble) {
1736 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
1738 fieldtype = fi->type;
1744 switch (fieldtype) {
1746 M_IST(REG_ZERO, s1, disp);
1749 M_STX(REG_ZERO, s1, disp);
1752 M_AST(REG_ZERO, s1, disp);
1755 M_FST(REG_ZERO, s1, disp);
1758 M_DST(REG_ZERO, s1, disp);
1764 /* branch operations **************************************************/
1766 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1769 M_INTMOVE(s1, REG_ITMP2_XPTR);
1771 #ifdef ENABLE_VERIFIER
1772 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1773 codegen_addpatchref(cd, PATCHER_athrow_areturn,
1774 iptr->sx.s23.s2.uc, 0);
1776 if (opt_showdisassemble) {
1780 #endif /* ENABLE_VERIFIER */
1782 disp = dseg_add_functionptr(cd, asm_handle_exception);
1783 M_ALD(REG_ITMP2, REG_PV, disp);
1784 M_JMP(REG_ITMP3_XPC, REG_ITMP2, REG_ZERO);
1786 M_NOP; /* nop ensures that XPC is less than the end */
1787 /* of basic block */
1791 case ICMD_GOTO: /* ... ==> ... */
1792 case ICMD_RET: /* ... ==> ... */
1795 codegen_addreference(cd, iptr->dst.block);
1800 case ICMD_JSR: /* ... ==> ... */
1803 codegen_addreference(cd, iptr->sx.s23.s3.jsrtarget.block);
1808 case ICMD_IFNULL: /* ..., value ==> ... */
1810 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1812 codegen_addreference(cd, iptr->dst.block);
1816 case ICMD_IFNONNULL: /* ..., value ==> ... */
1818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1820 codegen_addreference(cd, iptr->dst.block);
1824 case ICMD_IFEQ: /* ..., value ==> ... */
1826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1827 if (iptr->sx.val.i == 0) {
1830 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1831 M_CMP_IMM(s1, iptr->sx.val.i);
1834 ICONST(REG_ITMP2, iptr->sx.val.i);
1835 M_CMP(s1, REG_ITMP2);
1839 codegen_addreference(cd, iptr->dst.block);
1843 case ICMD_IFLT: /* ..., value ==> ... */
1845 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1846 if (iptr->sx.val.i == 0) {
1849 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1850 M_CMP_IMM(s1, iptr->sx.val.i);
1852 ICONST(REG_ITMP2, iptr->sx.val.i);
1853 M_CMP(s1, REG_ITMP2);
1857 codegen_addreference(cd, iptr->dst.block);
1861 case ICMD_IFLE: /* ..., value ==> ... */
1863 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1864 if (iptr->sx.val.i == 0) {
1868 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1869 M_CMP_IMM(s1, iptr->sx.val.i);
1872 ICONST(REG_ITMP2, iptr->sx.val.i);
1873 M_CMP(s1, REG_ITMP2);
1877 codegen_addreference(cd, iptr->dst.block);
1881 case ICMD_IFNE: /* ..., value ==> ... */
1883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1884 if (iptr->sx.val.i == 0) {
1888 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1889 M_CMP_IMM(s1, iptr->sx.val.i);
1892 ICONST(REG_ITMP2, iptr->sx.val.i);
1893 M_CMP(s1, REG_ITMP2);
1897 codegen_addreference(cd, iptr->dst.block);
1901 case ICMD_IFGT: /* ..., value ==> ... */
1903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1904 if (iptr->sx.val.i == 0) {
1907 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1908 M_CMP_IMM(s1, iptr->sx.val.i);
1910 ICONST(REG_ITMP2, iptr->sx.val.i);
1911 M_CMP(s1, REG_ITMP2);
1915 codegen_addreference(cd, iptr->dst.block);
1919 case ICMD_IFGE: /* ..., value ==> ... */
1921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1922 if (iptr->sx.val.i == 0) {
1926 if ((iptr->sx.val.i >= -4096) && (iptr->sx.val.i <= 4095)) {
1927 M_CMP_IMM(s1, iptr->sx.val.i);
1930 ICONST(REG_ITMP2, iptr->sx.val.i);
1931 M_CMP(s1, REG_ITMP2);
1935 codegen_addreference(cd, iptr->dst.block);
1939 case ICMD_IF_LEQ: /* ..., 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 LCONST(REG_ITMP2, iptr->sx.val.l);
1951 M_CMP(s1, REG_ITMP2);
1955 codegen_addreference(cd, iptr->dst.block);
1959 case ICMD_IF_LLT: /* ..., value ==> ... */
1961 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1962 if (iptr->sx.val.l == 0) {
1965 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1966 M_CMP_IMM(s1, iptr->sx.val.l);
1968 ICONST(REG_ITMP2, iptr->sx.val.l);
1969 M_CMP(s1, REG_ITMP2);
1973 codegen_addreference(cd, iptr->dst.block);
1977 case ICMD_IF_LLE: /* ..., value ==> ... */
1979 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1980 if (iptr->sx.val.l == 0) {
1984 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
1985 M_CMP_IMM(s1, iptr->sx.val.l);
1988 ICONST(REG_ITMP2, iptr->sx.val.l);
1989 M_CMP(s1, REG_ITMP2);
1993 codegen_addreference(cd, iptr->dst.block);
1997 case ICMD_IF_LNE: /* ..., 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.i);
2008 ICONST(REG_ITMP2, iptr->sx.val.l);
2009 M_CMP(s1, REG_ITMP2);
2013 codegen_addreference(cd, iptr->dst.block);
2017 case ICMD_IF_LGT: /* ..., value ==> ... */
2019 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2020 if (iptr->sx.val.l == 0) {
2023 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2024 M_CMP_IMM(s1, iptr->sx.val.l);
2026 ICONST(REG_ITMP2, iptr->sx.val.l);
2027 M_CMP(s1, REG_ITMP2);
2031 codegen_addreference(cd, iptr->dst.block);
2035 case ICMD_IF_LGE: /* ..., value ==> ... */
2037 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2038 if (iptr->sx.val.l == 0) {
2042 if ((iptr->sx.val.l >= -4096) && (iptr->sx.val.l <= 4095)) {
2043 M_CMP_IMM(s1, iptr->sx.val.l);
2046 ICONST(REG_ITMP2, iptr->sx.val.l);
2047 M_CMP(s1, REG_ITMP2);
2051 codegen_addreference(cd, iptr->dst.block);
2056 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
2057 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2059 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2060 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2063 codegen_addreference(cd, iptr->dst.block);
2067 case ICMD_IF_ICMPEQ: /* 32-bit compare */
2069 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2070 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2073 codegen_addreference(cd, iptr->dst.block);
2077 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
2078 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2080 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2081 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2084 codegen_addreference(cd, iptr->dst.block);
2088 case ICMD_IF_ICMPNE: /* 32-bit compare */
2090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2091 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2094 codegen_addreference(cd, iptr->dst.block);
2098 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2100 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2101 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2104 codegen_addreference(cd, iptr->dst.block);
2108 case ICMD_IF_ICMPLT: /* 32-bit compare */
2110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2111 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2114 codegen_addreference(cd, iptr->dst.block);
2118 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2120 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2121 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2124 codegen_addreference(cd, iptr->dst.block);
2128 case ICMD_IF_ICMPGT: /* 32-bit compare */
2130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2131 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2134 codegen_addreference(cd, iptr->dst.block);
2138 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2144 codegen_addreference(cd, iptr->dst.block);
2148 case ICMD_IF_ICMPLE: /* 32-bit compare */
2150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2151 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2154 codegen_addreference(cd, iptr->dst.block);
2159 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2161 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2162 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2165 codegen_addreference(cd, iptr->dst.block);
2169 case ICMD_IF_ICMPGE: /* 32-bit compare */
2171 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2172 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2175 codegen_addreference(cd, iptr->dst.block);
2180 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2183 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2184 M_INTMOVE(s1, REG_RESULT_CALLEE);
2185 goto nowperformreturn;
2187 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2189 s1 = emit_load_s1(jd, iptr, REG_RESULT_CALLEE);
2190 M_INTMOVE(s1, REG_RESULT_CALLEE);
2192 #ifdef ENABLE_VERIFIER
2193 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2194 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2195 iptr->sx.s23.s2.uc, 0);
2197 if (opt_showdisassemble) {
2201 #endif /* ENABLE_VERIFIER */
2202 goto nowperformreturn;
2204 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2207 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2208 M_FLTMOVE(s1, REG_FRESULT);
2209 goto nowperformreturn;
2211 case ICMD_RETURN: /* ... ==> ... */
2217 p = cd->stackframesize;
2219 #if !defined(NDEBUG)
2220 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2221 emit_verbosecall_exit(jd);
2224 #if defined(ENABLE_THREADS)
2225 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2226 /* XXX: REG_RESULT is save, but what about FRESULT? */
2227 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* XXX: what for ? */
2229 switch (iptr->opc) {
2232 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2236 disp = dseg_add_functionptr(cd, BUILTIN_monitorexit);
2237 M_ALD(REG_ITMP3, REG_PV, disp);
2238 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /*REG_RA_CALLER */
2240 switch (iptr->opc) {
2243 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2251 M_RETURN(REG_RA_CALLEE, 8); /* implicit window restore */
2257 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2260 branch_target_t *table;
2262 table = iptr->dst.table;
2264 l = iptr->sx.s23.s2.tablelow;
2265 i = iptr->sx.s23.s3.tablehigh;
2267 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2269 M_INTMOVE(s1, REG_ITMP1);
2271 else if (l <= 4095) {
2272 M_ADD_IMM(s1, -l, REG_ITMP1);
2275 ICONST(REG_ITMP2, l);
2276 /* XXX: do I need to truncate s1 to 32-bit ? */
2277 M_SUB(s1, REG_ITMP2, REG_ITMP1);
2285 M_CMP_IMM(REG_ITMP1, i);
2288 ICONST(REG_ITMP2, i);
2289 M_CMP(REG_ITMP1, REG_ITMP2);
2292 codegen_addreference(cd, table[0].block); /* default target */
2293 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
2295 /* build jump table top down and use address of lowest entry */
2300 dseg_add_target(cd, table->block);
2305 /* length of dataseg after last dseg_addtarget is used by load */
2307 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2308 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2309 M_JMP(REG_ZERO, REG_ITMP2, REG_ZERO);
2314 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2317 lookup_target_t *lookup;
2319 lookup = iptr->dst.lookup;
2321 i = iptr->sx.s23.s2.lookupcount;
2323 MCODECHECK((i<<2)+8);
2324 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2327 if ((lookup->value >= -4096) && (lookup->value <= 4095)) {
2328 M_CMP_IMM(s1, lookup->value);
2330 ICONST(REG_ITMP2, lookup->value);
2331 M_CMP(s1, REG_ITMP2);
2334 codegen_addreference(cd, lookup->target.block);
2340 codegen_addreference(cd, iptr->sx.s23.s3.lookupdefault.block);
2347 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
2349 bte = iptr->sx.s23.s3.bte;
2352 /* XXX: proper builtin calling and float args are so not implemented */
2353 assert(md->paramcount <= 5 && md->argfltreguse < 1);
2357 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2359 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2360 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2361 case ICMD_INVOKEINTERFACE:
2363 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2365 um = iptr->sx.s23.s3.um;
2366 md = um->methodref->parseddesc.md;
2369 lm = iptr->sx.s23.s3.fmiref->p.method;
2371 md = lm->parseddesc;
2375 s3 = md->paramcount;
2377 MCODECHECK((s3 << 1) + 64);
2379 /* copy arguments to registers or stack location */
2381 for (s3 = s3 - 1; s3 >= 0; s3--) {
2382 var = VAR(iptr->sx.s23.s2.args[s3]);
2384 if (var->flags & PREALLOC)
2387 if (IS_INT_LNG_TYPE(var->type)) {
2388 if (!md->params[s3].inmemory) {
2389 s1 = rd->argintregs[md->params[s3].regoff];
2390 d = emit_load(jd, iptr, var, s1);
2394 d = emit_load(jd, iptr, var, REG_ITMP1);
2395 M_STX(d, REG_SP, md->params[s3].regoff * 8);
2399 if (!md->params[s3].inmemory) {
2400 s1 = rd->argfltregs[md->params[s3].regoff];
2401 d = emit_load(jd, iptr, var, s1);
2402 if (IS_2_WORD_TYPE(var->type))
2408 d = emit_load(jd, iptr, var, REG_FTMP1);
2409 if (IS_2_WORD_TYPE(var->type))
2410 M_DST(d, REG_SP, md->params[s3].regoff * 8);
2412 M_FST(d, REG_SP, md->params[s3].regoff * 8);
2417 switch (iptr->opc) {
2419 disp = dseg_add_functionptr(cd, bte->fp);
2421 M_ALD(REG_PV_CALLER, REG_PV, disp); /* built-in-function pointer */
2424 /* c call, allocate parameter array */
2425 M_LDA(REG_SP, REG_SP, -(ABI_PARAMARRAY_SLOTS) * 8);
2429 case ICMD_INVOKESPECIAL:
2430 M_BEQZ(REG_OUT0, 0);
2431 codegen_add_nullpointerexception_ref(cd);
2435 case ICMD_INVOKESTATIC:
2437 disp = dseg_add_unique_address(cd, NULL);
2439 codegen_add_patch_ref(cd, PATCHER_invokestatic_special,
2443 disp = dseg_add_address(cd, lm->stubroutine);
2445 M_ALD(REG_PV_CALLER, REG_PV, disp); /* method pointer in pv */
2449 case ICMD_INVOKEVIRTUAL:
2450 gen_nullptr_check(REG_OUT0);
2453 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
2455 if (opt_showdisassemble) {
2462 s1 = OFFSET(vftbl_t, table[0]) +
2463 sizeof(methodptr) * lm->vftblindex;
2465 M_ALD(REG_METHODPTR, REG_OUT0,
2466 OFFSET(java_objectheader, vftbl));
2467 M_ALD(REG_PV_CALLER, REG_METHODPTR, s1);
2471 case ICMD_INVOKEINTERFACE:
2472 gen_nullptr_check(rd->argintregs[0]);
2475 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
2477 if (opt_showdisassemble) {
2485 s1 = OFFSET(vftbl_t, interfacetable[0]) -
2486 sizeof(methodptr*) * lm->class->index;
2488 s2 = sizeof(methodptr) * (lm - lm->class->methods);
2491 M_ALD(REG_METHODPTR, REG_OUT0,
2492 OFFSET(java_objectheader, vftbl));
2493 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
2494 M_ALD(REG_PV_CALLER, REG_METHODPTR, s2);
2499 /* generate the actual call */
2501 M_JMP(REG_RA_CALLER, s1, REG_ZERO);
2503 disp = (s4) (cd->mcodeptr - cd->mcodebase);
2504 /* REG_RA holds the value of the jmp instruction, therefore +8 */
2505 M_LDA(REG_ZERO, REG_RA_CALLER, -disp + 8);
2507 if (iptr->opc == ICMD_BUILTIN) {
2508 /* remove param slots */
2509 M_LDA(REG_SP, REG_SP, (ABI_PARAMARRAY_SLOTS) * 8);
2513 /* actually only used for ICMD_BUILTIN */
2515 if (INSTRUCTION_MUST_CHECK(iptr)) {
2516 M_BEQZ(REG_RESULT_CALLER, 0);
2517 codegen_add_fillinstacktrace_ref(cd);
2521 /* store return value */
2523 d = md->returntype.type;
2525 if (d != TYPE_VOID) {
2526 if (IS_INT_LNG_TYPE(d)) {
2527 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_CALLER);
2528 M_INTMOVE(REG_RESULT_CALLER, s1);
2531 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
2532 if (IS_2_WORD_TYPE(d)) {
2533 M_DBLMOVE(REG_FRESULT, s1);
2535 M_FLTMOVE(REG_FRESULT, s1);
2538 emit_store_dst(jd, iptr, s1);
2543 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
2544 /* XXX needs manual attention! */
2545 /* val.a: (classinfo*) superclass */
2547 /* superclass is an interface:
2549 * OK if ((sub == NULL) ||
2550 * (sub->vftbl->interfacetablelength > super->index) &&
2551 * (sub->vftbl->interfacetable[-super->index] != NULL));
2553 * superclass is a class:
2555 * OK if ((sub == NULL) || (0
2556 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
2557 * super->vftbl->diffvall));
2560 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
2562 vftbl_t *supervftbl;
2565 super = iptr->sx.s23.s3.c.cls;
2567 if (super == NULL) {
2572 superindex = super->index;
2573 supervftbl = super->vftbl;
2576 #if defined(ENABLE_THREADS)
2577 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
2580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2582 /* calculate interface checkcast code size */
2586 s2 += (opt_showdisassemble ? 2 : 0);
2588 /* calculate class checkcast code size */
2590 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
2592 s3 += (opt_showdisassemble ? 2 : 0);
2594 /* if class is not resolved, check which code to call */
2596 if (super == NULL) {
2597 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
2600 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
2602 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
2603 iptr->sx.s23.s3.c.ref,
2606 if (opt_showdisassemble) {
2610 M_ILD(REG_ITMP2, REG_PV, disp);
2611 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
2612 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
2616 /* interface checkcast code */
2618 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
2619 if (super == NULL) {
2620 codegen_addpatchref(cd,
2621 PATCHER_checkcast_instanceof_interface,
2622 iptr->sx.s23.s3.c.ref,
2625 if (opt_showdisassemble) {
2634 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2635 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
2636 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
2637 M_BLEZ(REG_ITMP3, 0);
2638 codegen_add_classcastexception_ref(cd, s1);
2640 M_ALD(REG_ITMP3, REG_ITMP2,
2641 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
2642 superindex * sizeof(methodptr*)));
2643 M_BEQZ(REG_ITMP3, 0);
2644 codegen_add_classcastexception_ref(cd, s1);
2647 if (super == NULL) {
2653 /* class checkcast code */
2655 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
2656 if (super == NULL) {
2657 disp = dseg_add_unique_address(cd, NULL);
2659 codegen_addpatchref(cd,
2660 PATCHER_checkcast_instanceof_class,
2661 iptr->sx.s23.s3.c.ref,
2664 if (opt_showdisassemble) {
2669 disp = dseg_add_address(cd, supervftbl);
2675 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
2676 M_ALD(REG_ITMP3, REG_PV, disp);
2677 #if defined(ENABLE_THREADS)
2678 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
2680 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
2681 /* if (s1 != REG_ITMP1) { */
2682 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
2683 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
2684 /* #if defined(ENABLE_THREADS) */
2685 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
2687 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
2690 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
2691 M_SUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2692 M_ALD(REG_ITMP3, REG_PV, disp);
2693 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
2694 #if defined(ENABLE_THREADS)
2695 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
2698 M_CMP(REG_ITMP3, REG_ITMP2);
2699 M_BULT(0); /* branch if ITMP3 < ITMP2 */
2700 codegen_add_classcastexception_ref(cd, s1);
2704 d = codegen_reg_of_dst(jd, iptr, s1);
2707 /* array type cast-check */
2709 s1 = emit_load_s1(jd, iptr, rd->argintregs[0]);
2710 M_INTMOVE(s1, rd->argintregs[0]);
2712 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
2714 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2715 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
2716 iptr->sx.s23.s3.c.ref,
2719 if (opt_showdisassemble) {
2724 M_ALD(rd->argintregs[1], REG_PV, disp);
2725 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
2726 M_ALD(REG_ITMP3, REG_PV, disp);
2727 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2731 M_BEQZ(REG_RESULT_CALLER, 0);
2732 codegen_add_classcastexception_ref(cd, s1);
2735 d = codegen_reg_of_dst(jd, iptr, s1);
2739 emit_store_dst(jd, iptr, d);
2745 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
2750 } /* for instruction */
2754 } /* if (bptr -> flags >= BBREACHED) */
2755 } /* for basic block */
2757 dseg_createlinenumbertable(cd);
2759 /* generate exception and patcher stubs */
2761 emit_exception_stubs(jd);
2762 emit_patcher_stubs(jd);
2763 emit_replacement_stubs(jd);
2767 /* everything's ok */
2776 /* createcompilerstub **********************************************************
2778 Creates a stub routine which calls the compiler.
2780 *******************************************************************************/
2782 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
2783 #define COMPILERSTUB_CODESIZE 4 * 4
2785 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
2788 u1 *createcompilerstub(methodinfo *m)
2790 u1 *s; /* memory to hold the stub */
2796 s = CNEW(u1, COMPILERSTUB_SIZE);
2798 /* set data pointer and code pointer */
2801 s = s + COMPILERSTUB_DATASIZE;
2803 /* mark start of dump memory area */
2805 dumpsize = dump_size();
2807 cd = DNEW(codegendata);
2810 /* Store the codeinfo pointer in the same place as in the
2811 methodheader for compiled methods. */
2813 code = code_codeinfo_new(m);
2815 d[0] = (ptrint) asm_call_jit_compiler;
2817 d[2] = (ptrint) code;
2819 /* code for the stub */
2820 /* no window save yet, user caller's PV */
2821 M_ALD_INTERN(REG_ITMP1, REG_PV_CALLER, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
2822 M_ALD_INTERN(REG_PV_CALLER, REG_PV_CALLER, -3 * SIZEOF_VOID_P); /* pointer to compiler */
2823 M_JMP(REG_ZERO, REG_PV_CALLER, REG_ZERO); /* jump to the compiler, RA is wasted */
2826 #if defined(ENABLE_STATISTICS)
2828 count_cstub_len += COMPILERSTUB_SIZE;
2831 /* release dump area */
2833 dump_release(dumpsize);
2840 /* createnativestub ************************************************************
2842 Creates a stub routine which calls a native method.
2844 *******************************************************************************/
2846 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
2854 s4 i, j; /* count variables */
2857 s4 funcdisp; /* displacement of the function */
2859 /* get required compiler data */
2866 /* rewrite registers and params */
2867 md_native_reg_setup(jd);
2868 md_native_param_alloc(nmd);
2870 /* initialize variables */
2873 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
2875 /* calculate stack frame size */
2877 cd->stackframesize =
2878 sizeof(stackframeinfo) / SIZEOF_VOID_P +
2879 sizeof(localref_table) / SIZEOF_VOID_P +
2880 md->paramcount + /* for saving arguments over calls */
2881 nmd->memuse + /* nmd knows about the native stackframe layout */
2884 /* create method header */
2886 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
2887 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
2888 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
2889 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
2890 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
2891 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
2892 (void) dseg_addlinenumbertablesize(cd);
2893 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
2895 /* generate stub code */
2897 M_SAVE(REG_SP, -cd->stackframesize * 8, REG_SP); /* build up stackframe */
2899 #if !defined(NDEBUG)
2900 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2901 emit_verbosecall_enter(jd);
2904 /* get function address (this must happen before the stackframeinfo) */
2906 funcdisp = dseg_add_functionptr(cd, f);
2908 #if !defined(WITH_STATIC_CLASSPATH)
2910 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
2912 if (opt_showdisassemble) {
2918 /* save float argument registers */
2920 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
2921 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
2922 M_DST(rd->argfltregs[i], REG_SP, j * 8);
2927 /* prepare data structures for native function call */
2929 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp == top of the stack frame (absolute == +BIAS) */
2930 M_MOV(REG_PV_CALLEE, REG_OUT1);
2931 M_MOV(REG_FP, REG_OUT2); /* java sp */
2932 M_MOV(REG_RA_CALLEE, REG_OUT3);
2933 disp = dseg_add_functionptr(cd, codegen_start_native_call);
2934 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
2935 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
2936 M_NOP; /* XXX fill me! */
2938 /* restore float argument registers */
2940 for (i = 0, j = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
2941 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
2942 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
2947 /* copy or spill arguments to new locations */
2948 int num_fltregargs = 0;
2949 int fltregarg_inswap[16];
2950 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
2951 t = md->paramtypes[i].type;
2953 if (IS_INT_LNG_TYPE(t)) {
2954 if (!md->params[i].inmemory) {
2955 s1 = rd->argintregs[md->params[i].regoff];
2956 /* s1 refers to the old window, transpose */
2957 s1 = REG_WINDOW_TRANSPOSE(s1);
2959 if (!nmd->params[j].inmemory) {
2960 s2 = nat_argintregs[nmd->params[j].regoff];
2963 s2 = nmd->params[j].regoff;
2964 M_AST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
2968 s1 = md->params[i].regoff + cd->stackframesize;
2969 s2 = nmd->params[j].regoff;
2970 M_ALD(REG_ITMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
2971 M_AST(REG_ITMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
2975 if (!md->params[i].inmemory) {
2976 s1 = rd->argfltregs[md->params[i].regoff];
2978 if (!nmd->params[j].inmemory) {
2979 /* no mapping to regs needed, native flt args use regoff */
2980 s2 = nmd->params[j].regoff;
2982 /* we cannot move flt regs to their native arg locations directly */
2983 M_DMOV(s1, s2 + 16);
2984 fltregarg_inswap[num_fltregargs] = s2;
2986 printf("flt arg swap to %d\n", s2 + 16);
2989 s2 = nmd->params[j].regoff;
2990 if (IS_2_WORD_TYPE(t))
2991 M_DST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
2993 M_FST(s1, REG_SP, USESTACK_PARAMS + s2 * 8);
2997 s1 = md->params[i].regoff + cd->stackframesize;
2998 s2 = nmd->params[j].regoff;
2999 if (IS_2_WORD_TYPE(t)) {
3000 M_DLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
3001 M_DST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
3003 M_FLD(REG_FTMP1, REG_SP, USESTACK_PARAMS + s1 * 8);
3004 M_FST(REG_FTMP1, REG_SP, USESTACK_PARAMS + s2 * 8);
3010 /* move swapped float args to target regs */
3011 for (i = 0; i < num_fltregargs; i++) {
3012 s1 = fltregarg_inswap[i];
3013 M_DMOV(s1 + 16, s1);
3014 printf("float arg to target reg: %d ==> %d\n", s1+16, s1);
3018 /* put class into second argument register */
3020 if (m->flags & ACC_STATIC) {
3021 disp = dseg_add_address(cd, m->class);
3022 M_ALD(REG_OUT1, REG_PV_CALLEE, disp);
3025 /* put env into first argument register */
3027 disp = dseg_add_address(cd, _Jv_env);
3028 M_ALD(REG_OUT0, REG_PV_CALLEE, disp);
3030 /* do the native function call */
3032 M_ALD(REG_ITMP3, REG_PV_CALLEE, funcdisp); /* load adress of native method */
3033 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO); /* call native method */
3034 M_NOP; /* delay slot */
3036 /* save return value */
3038 if (md->returntype.type != TYPE_VOID) {
3039 if (IS_INT_LNG_TYPE(md->returntype.type))
3040 M_MOV(REG_RESULT_CALLER, REG_RESULT_CALLEE);
3042 M_DST(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3045 /* Note: native functions return float values in %f0 (see ABI) */
3046 /* we handle this by doing M_FLD below. (which will load the lower word into %f1) */
3048 #if !defined(NDEBUG)
3049 /* But for the trace function we need to put a flt result into %f1 */
3050 if (JITDATA_HAS_FLAG_VERBOSECALL(jd)) {
3051 if (!IS_2_WORD_TYPE(md->returntype.type))
3052 M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3053 emit_verbosecall_exit(jd);
3057 /* remove native stackframe info */
3059 M_ADD_IMM(REG_FP, BIAS, REG_OUT0); /* datasp, like above */
3060 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3061 M_ALD(REG_ITMP3, REG_PV_CALLEE, disp);
3062 M_JMP(REG_RA_CALLER, REG_ITMP3, REG_ZERO);
3063 M_NOP; /* XXX fill me! */
3064 M_MOV(REG_RESULT_CALLER, REG_ITMP2_XPTR);
3066 /* restore float return value, int return value already in our return reg */
3068 if (md->returntype.type != TYPE_VOID) {
3069 if (IS_FLT_DBL_TYPE(md->returntype.type)) {
3070 if (IS_2_WORD_TYPE(md->returntype.type))
3071 M_DLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3073 M_FLD(REG_FRESULT, REG_SP, USESTACK_PARAMS);
3077 /* check for exception */
3079 M_BNEZ(REG_ITMP2_XPTR, 4); /* if no exception then return */
3080 M_RESTORE(REG_ZERO, 0, REG_ZERO); /* restore callers window (DELAY) */
3082 M_RET(REG_RA_CALLER, 8); /* return to caller */
3083 M_NOP; /* DELAY SLOT */
3085 /* handle exception */
3087 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
3088 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
3089 M_JMP(REG_ZERO, REG_ITMP3, REG_ZERO);/* jump to asm exception handler */
3090 M_MOV(REG_RA_CALLER, REG_ITMP3_XPC); /* get exception address (DELAY) */
3092 /* generate patcher stubs */
3094 emit_patcher_stubs(jd);
3098 return code->entrypoint;
3102 * These are local overrides for various environment variables in Emacs.
3103 * Please do not remove this and leave it at the end of the file, where
3104 * Emacs will automagically detect them.
3105 * ---------------------------------------------------------------------
3108 * indent-tabs-mode: t
3112 * vim:noexpandtab:sw=4:ts=4: