1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 $Id: codegen.c 7682 2007-04-10 21:24:14Z twisti $
39 #include "vm/jit/mips/arch.h"
40 #include "vm/jit/mips/codegen.h"
42 #include "mm/memory.h"
44 #include "native/native.h"
46 #if defined(ENABLE_THREADS)
47 # include "threads/native/lock.h"
50 #include "vm/builtin.h"
51 #include "vm/exceptions.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen-common.h"
56 #include "vm/jit/dseg.h"
57 #include "vm/jit/emit-common.h"
58 #include "vm/jit/jit.h"
59 #include "vm/jit/md.h"
60 #include "vm/jit/patcher.h"
61 #include "vm/jit/reg.h"
62 #include "vm/jit/replace.h"
64 #if defined(ENABLE_LSRA)
65 # include "vm/jit/allocator/lsra.h"
68 #include "vmcore/class.h"
69 #include "vmcore/options.h"
72 /* codegen_emit ****************************************************************
74 Generates machine code.
76 *******************************************************************************/
78 bool codegen_emit(jitdata *jd)
84 s4 len, s1, s2, s3, d, disp;
90 constant_classref *cr;
92 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
93 unresolved_method *um;
94 builtintable_entry *bte;
101 /* get required compiler data */
108 /* prevent compiler warnings */
123 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
125 /* space to save used callee saved registers */
127 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
128 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
130 cd->stackframesize = rd->memuse + savedregs_num;
132 #if defined(ENABLE_THREADS)
133 /* space to save argument of monitor_enter */
135 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
136 # if SIZEOF_VOID_P == 8
137 cd->stackframesize++;
140 cd->stackframesize += 2;
145 /* keep stack 16-byte aligned */
147 if (cd->stackframesize & 1)
148 cd->stackframesize++;
150 /* create method header */
152 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
153 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
155 #if defined(ENABLE_THREADS)
156 /* IsSync contains the offset relative to the stack pointer for the
157 argument of monitor_exit used in the exception handler. Since the
158 offset could be zero and give a wrong meaning of the flag it is
162 if (checksync && (m->flags & ACC_SYNCHRONIZED))
163 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
166 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
168 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
169 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
170 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
171 dseg_addlinenumbertablesize(cd);
172 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
174 /* create exception table */
176 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
177 dseg_add_target(cd, ex->start);
178 dseg_add_target(cd, ex->end);
179 dseg_add_target(cd, ex->handler);
180 (void) dseg_add_unique_address(cd, ex->catchtype.any);
183 /* create stack frame (if necessary) */
185 if (cd->stackframesize)
186 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
188 /* save return address and used callee saved registers */
190 p = cd->stackframesize;
191 if (!jd->isleafmethod) {
192 p--; M_AST(REG_RA, REG_SP, p * 8);
194 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
195 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
197 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
198 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
201 /* take arguments out of register or stack frame */
205 for (p = 0, l = 0; p < md->paramcount; p++) {
206 t = md->paramtypes[p].type;
208 varindex = jd->local_map[l * 5 + t];
211 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
214 if (varindex == UNUSED)
219 s1 = md->params[p].regoff;
220 if (IS_INT_LNG_TYPE(t)) { /* integer args */
221 if (!md->params[p].inmemory) { /* register arguments */
222 #if SIZEOF_VOID_P == 8
223 s2 = rd->argintregs[s1];
224 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
225 M_INTMOVE(s2, var->vv.regoff);
226 } else { /* reg arg -> spilled */
227 M_LST(s2, REG_SP, var->vv.regoff * 8);
230 if (IS_2_WORD_TYPE(t)) {
231 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
232 rd->argintregs[GET_HIGH_REG(s1)]);
233 if (!(var->flags & INMEMORY)) /* reg arg -> register */
234 M_LNGMOVE(s2, var->vv.regoff);
235 else /* reg arg -> spilled */
236 M_LST(s2, REG_SP, var->vv.regoff * 8);
239 s2 = rd->argintregs[s1];
240 if (!(var->flags & INMEMORY)) /* reg arg -> register */
241 M_INTMOVE(s2, var->vv.regoff);
242 else /* reg arg -> spilled */
243 M_IST(s2, REG_SP, var->vv.regoff * 8);
246 } else { /* stack arguments */
247 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
248 #if SIZEOF_VOID_P == 8
249 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
251 if (IS_2_WORD_TYPE(t))
252 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
254 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
256 } else { /* stack arg -> spilled */
257 var->vv.regoff = cd->stackframesize + s1;
261 } else { /* floating args */
262 if (!md->params[p].inmemory) { /* register arguments */
263 #if SIZEOF_VOID_P == 8
264 s2 = rd->argfltregs[s1];
265 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
266 if (IS_2_WORD_TYPE(t))
267 M_DMOV(s2, var->vv.regoff);
269 M_FMOV(s2, var->vv.regoff);
270 } else { /* reg arg -> spilled */
271 if (IS_2_WORD_TYPE(t))
272 M_DST(s2, REG_SP, var->vv.regoff * 8);
274 M_FST(s2, REG_SP, var->vv.regoff * 8);
278 ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
279 s2 = rd->argfltregs[s1];
280 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
281 if (IS_2_WORD_TYPE(t))
282 M_DBLMOVE(s2, var->vv.regoff);
284 M_FLTMOVE(s2, var->vv.regoff);
286 else { /* reg arg -> spilled */
287 if (IS_2_WORD_TYPE(t))
288 M_DST(s2, REG_SP, var->vv.regoff * 8);
290 M_FST(s2, REG_SP, var->vv.regoff * 8);
294 if (IS_2_WORD_TYPE(t)) {
295 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
296 rd->argintregs[GET_HIGH_REG(s1)]);
297 if (!(var->flags & INMEMORY)) {
298 M_MTC1(GET_LOW_REG(s2), var->vv.regoff);
299 M_MTC1(GET_HIGH_REG(s2), var->vv.regoff + 1);
303 M_LST(s2, REG_SP, var->vv.regoff * 8);
306 s2 = rd->argintregs[s1];
307 if (!(var->flags & INMEMORY)) {
308 M_MTC1(s2, var->vv.regoff);
312 M_IST(s2, REG_SP, var->vv.regoff * 8);
317 } else { /* stack arguments */
318 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
319 if (IS_2_WORD_TYPE(t))
320 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
322 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
323 } else /* stack-arg -> spilled */
324 var->vv.regoff = cd->stackframesize + s1;
329 /* call monitorenter function */
331 #if defined(ENABLE_THREADS)
332 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
333 /* stack offset for monitor argument */
337 # if !defined(NDEBUG)
338 if (opt_verbosecall) {
339 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
341 for (p = 0; p < INT_ARG_CNT; p++)
342 M_AST(rd->argintregs[p], REG_SP, p * 8);
344 for (p = 0; p < FLT_ARG_CNT; p++)
345 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
347 s1 += INT_ARG_CNT + FLT_ARG_CNT;
351 /* get correct lock object */
353 if (m->flags & ACC_STATIC) {
354 disp = dseg_add_address(cd, &m->class->object.header);
355 M_ALD(REG_A0, REG_PV, disp);
356 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
357 M_ALD(REG_ITMP3, REG_PV, disp);
360 /* emit_nullpointer_check(cd, iptr, REG_A0); */
362 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
363 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
364 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
367 M_JSR(REG_RA, REG_ITMP3);
368 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
370 # if !defined(NDEBUG)
371 if (opt_verbosecall) {
372 for (p = 0; p < INT_ARG_CNT; p++)
373 M_ALD(rd->argintregs[p], REG_SP, p * 8);
375 for (p = 0; p < FLT_ARG_CNT; p++)
376 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
379 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
387 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
388 emit_verbosecall_enter(jd);
391 /* end of header generation */
393 /* create replacement points */
395 REPLACEMENT_POINTS_INIT(cd, jd);
397 /* walk through all basic blocks */
399 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
401 /* handle replacement points */
403 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
405 /* store relative start of block */
407 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
409 if (bptr->flags >= BBREACHED) {
410 /* branch resolving */
412 codegen_resolve_branchrefs(cd, bptr);
414 /* copy interface registers to their destination */
418 #if defined(ENABLE_LSRA)
422 src = bptr->invars[len];
423 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
424 /* d = reg_of_var(m, src, REG_ITMP1); */
425 if (!(src->flags & INMEMORY))
429 M_INTMOVE(REG_ITMP1, d);
430 emit_store(jd, NULL, src, d);
437 var = VAR(bptr->invars[len]);
438 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
439 d = codegen_reg_of_var(0, var, REG_ITMP1);
440 M_INTMOVE(REG_ITMP1, d);
441 emit_store(jd, NULL, var, d);
444 assert((var->flags & INOUT));
447 #if defined(ENABLE_LSRA)
450 /* walk through all instructions */
453 /* currentline = 0; */
455 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
456 if (iptr->line != currentline) {
457 dseg_addlinenumber(cd, iptr->line);
458 currentline = iptr->line;
461 MCODECHECK(64); /* an instruction usually needs < 64 words */
465 case ICMD_NOP: /* ... ==> ... */
466 case ICMD_POP: /* ..., value ==> ... */
467 case ICMD_POP2: /* ..., value, value ==> ... */
470 case ICMD_INLINE_START:
472 REPLACEMENT_POINT_INLINE_START(cd, iptr);
475 case ICMD_INLINE_BODY:
477 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
478 dseg_addlinenumber_inline_start(cd, iptr);
479 dseg_addlinenumber(cd, iptr->line);
482 case ICMD_INLINE_END:
484 dseg_addlinenumber_inline_end(cd, iptr);
485 dseg_addlinenumber(cd, iptr->line);
488 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
490 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
491 emit_nullpointer_check(cd, iptr, s1);
494 /* constant operations ************************************************/
496 case ICMD_ICONST: /* ... ==> ..., constant */
498 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
499 ICONST(d, iptr->sx.val.i);
500 emit_store_dst(jd, iptr, d);
503 case ICMD_LCONST: /* ... ==> ..., constant */
505 #if SIZEOF_VOID_P == 8
506 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
508 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
510 LCONST(d, iptr->sx.val.l);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_FCONST: /* ... ==> ..., constant */
516 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
517 disp = dseg_add_float(cd, iptr->sx.val.f);
518 M_FLD(d, REG_PV, disp);
519 emit_store_dst(jd, iptr, d);
522 case ICMD_DCONST: /* ... ==> ..., constant */
524 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
525 disp = dseg_add_double(cd, iptr->sx.val.d);
526 M_DLD(d, REG_PV, disp);
527 emit_store_dst(jd, iptr, d);
530 case ICMD_ACONST: /* ... ==> ..., constant */
532 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
534 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
535 cr = iptr->sx.val.c.ref;
536 disp = dseg_add_unique_address(cd, cr);
538 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
540 M_ALD(d, REG_PV, disp);
543 if (iptr->sx.val.anyptr == NULL)
544 M_INTMOVE(REG_ZERO, d);
546 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
547 M_ALD(d, REG_PV, disp);
550 emit_store_dst(jd, iptr, d);
554 /* load/store/copy/move operations ************************************/
556 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
557 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
558 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
559 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
560 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
561 case ICMD_ISTORE: /* ..., value ==> ... */
562 case ICMD_LSTORE: /* ..., value ==> ... */
563 case ICMD_FSTORE: /* ..., value ==> ... */
564 case ICMD_DSTORE: /* ..., value ==> ... */
568 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
572 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
573 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
577 /* integer operations *************************************************/
579 case ICMD_INEG: /* ..., value ==> ..., - value */
581 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
583 M_ISUB(REG_ZERO, s1, d);
584 emit_store_dst(jd, iptr, d);
587 case ICMD_LNEG: /* ..., value ==> ..., - value */
589 #if SIZEOF_VOID_P == 8
590 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
591 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
592 M_LSUB(REG_ZERO, s1, d);
594 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
595 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
596 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
597 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
598 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
599 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
601 emit_store_dst(jd, iptr, d);
604 case ICMD_I2L: /* ..., value ==> ..., value */
606 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
607 #if SIZEOF_VOID_P == 8
608 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
612 M_INTMOVE(s1, GET_LOW_REG(d));
613 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
615 emit_store_dst(jd, iptr, d);
618 case ICMD_L2I: /* ..., value ==> ..., value */
620 #if SIZEOF_VOID_P == 8
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
623 M_ISLL_IMM(s1, 0, d);
625 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
626 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
627 M_INTMOVE(GET_LOW_REG(s1), d);
629 emit_store_dst(jd, iptr, d);
632 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
634 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
635 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
636 #if SIZEOF_VOID_P == 8
637 M_LSLL_IMM(s1, 56, d);
638 M_LSRA_IMM( d, 56, d);
640 M_ISLL_IMM(s1, 24, d);
641 M_ISRA_IMM( d, 24, d);
643 emit_store_dst(jd, iptr, d);
646 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
648 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
650 M_AND_IMM(s1, 0xffff, d);
651 emit_store_dst(jd, iptr, d);
654 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
658 #if SIZEOF_VOID_P == 8
659 M_LSLL_IMM(s1, 48, d);
660 M_LSRA_IMM( d, 48, d);
662 M_ISLL_IMM(s1, 16, d);
663 M_ISRA_IMM( d, 16, d);
665 emit_store_dst(jd, iptr, d);
669 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
671 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
672 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
675 emit_store_dst(jd, iptr, d);
679 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
680 /* sx.val.i = constant */
682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
685 M_IADD_IMM(s1, iptr->sx.val.i, d);
687 ICONST(REG_ITMP2, iptr->sx.val.i);
688 M_IADD(s1, REG_ITMP2, d);
690 emit_store_dst(jd, iptr, d);
693 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
695 #if SIZEOF_VOID_P == 8
696 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
697 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
701 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
702 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
703 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
704 M_IADD(s1, s2, GET_HIGH_REG(d));
705 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
706 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
707 if (s1 == GET_LOW_REG(d)) {
708 M_MOV(s1, REG_ITMP3);
711 M_IADD(s1, s2, GET_LOW_REG(d));
712 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
713 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
715 emit_store_dst(jd, iptr, d);
718 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
719 /* sx.val.l = constant */
721 #if SIZEOF_VOID_P == 8
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
724 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
725 M_LADD_IMM(s1, iptr->sx.val.l, d);
727 LCONST(REG_ITMP2, iptr->sx.val.l);
728 M_LADD(s1, REG_ITMP2, d);
731 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
732 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
733 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
734 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
735 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
736 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
738 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
739 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
740 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
741 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
742 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
743 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
744 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
747 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
748 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
749 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
750 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
751 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
752 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
753 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
754 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
757 emit_store_dst(jd, iptr, d);
760 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
762 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
763 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
764 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
766 emit_store_dst(jd, iptr, d);
769 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
770 /* sx.val.i = constant */
772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
773 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
774 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
775 M_IADD_IMM(s1, -iptr->sx.val.i, d);
777 ICONST(REG_ITMP2, iptr->sx.val.i);
778 M_ISUB(s1, REG_ITMP2, d);
780 emit_store_dst(jd, iptr, d);
783 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
785 #if SIZEOF_VOID_P == 8
786 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
787 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
791 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
792 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
794 M_ISUB(s1, s2, GET_HIGH_REG(d));
795 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
796 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
797 M_CMPULT(s1, s2, REG_ITMP3);
798 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
799 /* if s1 is equal to REG_ITMP3 we have to reload it, since
800 the CMPULT instruction destroyed it */
802 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
803 M_ISUB(s1, s2, GET_LOW_REG(d));
806 emit_store_dst(jd, iptr, d);
809 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
810 /* sx.val.l = constant */
812 #if SIZEOF_VOID_P == 8
813 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
814 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
815 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
816 M_LADD_IMM(s1, -iptr->sx.val.l, d);
818 LCONST(REG_ITMP2, iptr->sx.val.l);
819 M_LSUB(s1, REG_ITMP2, d);
822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
823 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
824 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
825 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
826 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
827 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
828 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
829 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
831 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
832 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
833 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
834 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
835 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
838 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
839 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
840 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
841 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
842 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
843 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
844 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
845 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
848 emit_store_dst(jd, iptr, d);
851 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
855 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
864 /* sx.val.i = constant */
866 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 ICONST(REG_ITMP2, iptr->sx.val.i);
869 M_IMUL(s1, REG_ITMP2);
873 emit_store_dst(jd, iptr, d);
876 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
878 #if SIZEOF_VOID_P == 8
879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
880 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
881 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
887 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
888 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
889 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
894 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
896 M_MFHI(GET_HIGH_REG(d));
897 M_MFLO(GET_LOW_REG(d));
900 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
902 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
903 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
906 /* XXX do we need nops here? */
908 emit_store_dst(jd, iptr, d);
911 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
912 /* sx.val.l = constant */
914 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
915 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
916 LCONST(REG_ITMP2, iptr->sx.val.l);
917 M_LMUL(s1, REG_ITMP2);
921 emit_store_dst(jd, iptr, d);
924 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
927 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
928 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
929 emit_arithmetic_check(cd, iptr, s2);
934 emit_store_dst(jd, iptr, d);
937 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
940 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
941 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
942 emit_arithmetic_check(cd, iptr, s2);
947 emit_store_dst(jd, iptr, d);
950 #if SIZEOF_VOID_P == 8
952 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
954 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
955 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
956 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
957 emit_arithmetic_check(cd, iptr, s2);
962 emit_store_dst(jd, iptr, d);
965 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
968 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
969 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
970 emit_arithmetic_check(cd, iptr, s2);
975 emit_store_dst(jd, iptr, d);
978 #else /* SIZEOF_VOID_P == 8 */
980 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
981 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
983 bte = iptr->sx.s23.s3.bte;
986 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
987 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
988 emit_arithmetic_check(cd, iptr, REG_ITMP3);
990 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
991 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
994 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
995 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
996 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
999 disp = dseg_add_functionptr(cd, bte->fp);
1000 M_ALD(REG_ITMP3, REG_PV, disp);
1001 M_JSR(REG_RA, REG_ITMP3);
1004 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1005 M_LNGMOVE(REG_RESULT_PACKED, d);
1006 emit_store_dst(jd, iptr, d);
1009 #endif /* SIZEOF_VOID_P == 8 */
1011 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1012 /* val.i = constant */
1014 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1015 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1016 #if SIZEOF_VOID_P == 8
1017 M_LSRA_IMM(s1, 63, REG_ITMP2);
1018 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1019 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1020 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1022 M_ISRA_IMM(s1, 31, REG_ITMP2);
1023 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
1024 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1025 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1027 emit_store_dst(jd, iptr, d);
1030 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1031 /* val.i = constant */
1033 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1034 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1036 M_MOV(s1, REG_ITMP1);
1039 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1040 M_AND_IMM(s1, iptr->sx.val.i, d);
1043 M_ISUB(REG_ZERO, s1, d);
1044 M_AND_IMM(d, iptr->sx.val.i, d);
1047 ICONST(REG_ITMP2, iptr->sx.val.i);
1048 M_AND(s1, REG_ITMP2, d);
1051 M_ISUB(REG_ZERO, s1, d);
1052 M_AND(d, REG_ITMP2, d);
1054 M_ISUB(REG_ZERO, d, d);
1055 emit_store_dst(jd, iptr, d);
1058 #if SIZEOF_VOID_P == 8
1060 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1061 /* val.i = constant */
1063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1064 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1065 M_LSRA_IMM(s1, 63, REG_ITMP2);
1066 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1067 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1068 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1073 /* val.l = constant */
1075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1078 M_MOV(s1, REG_ITMP1);
1081 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1082 M_AND_IMM(s1, iptr->sx.val.l, d);
1085 M_LSUB(REG_ZERO, s1, d);
1086 M_AND_IMM(d, iptr->sx.val.l, d);
1089 LCONST(REG_ITMP2, iptr->sx.val.l);
1090 M_AND(s1, REG_ITMP2, d);
1093 M_LSUB(REG_ZERO, s1, d);
1094 M_AND(d, REG_ITMP2, d);
1096 M_LSUB(REG_ZERO, d, d);
1097 emit_store_dst(jd, iptr, d);
1100 #endif /* SIZEOF_VOID_P == 8 */
1102 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1104 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1105 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1106 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1108 emit_store_dst(jd, iptr, d);
1111 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1112 /* sx.val.i = constant */
1114 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1115 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1116 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1117 emit_store_dst(jd, iptr, d);
1120 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1122 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1123 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1124 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1126 emit_store_dst(jd, iptr, d);
1129 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1130 /* sx.val.i = constant */
1132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1134 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1144 emit_store_dst(jd, iptr, d);
1147 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1148 /* sx.val.i = constant */
1150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1152 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1158 #if SIZEOF_VOID_P == 8
1159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1160 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1164 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1165 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1166 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1168 M_ISLL(s2, 26, REG_ITMP1);
1169 M_BGEZ(REG_ITMP1, 3);
1172 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1174 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1177 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1179 M_BEQZ(REG_ITMP1, 4);
1180 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1182 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1183 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1184 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1187 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1190 emit_store_dst(jd, iptr, d);
1193 #if SIZEOF_VOID_P == 8
1195 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1196 /* sx.val.i = constant */
1198 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1199 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1200 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1201 emit_store_dst(jd, iptr, d);
1204 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1206 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1207 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1208 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1210 emit_store_dst(jd, iptr, d);
1213 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1214 /* sx.val.i = constant */
1216 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1217 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1218 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1219 emit_store_dst(jd, iptr, d);
1222 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1224 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1225 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1226 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1228 emit_store_dst(jd, iptr, d);
1231 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1232 /* sx.val.i = constant */
1234 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1235 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1236 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1237 emit_store_dst(jd, iptr, d);
1240 #endif /* SIZEOF_VOID_P == 8 */
1242 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1244 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1245 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1246 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1248 emit_store_dst(jd, iptr, d);
1251 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1252 /* sx.val.i = constant */
1254 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1255 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1256 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1257 M_AND_IMM(s1, iptr->sx.val.i, d);
1259 ICONST(REG_ITMP2, iptr->sx.val.i);
1260 M_AND(s1, REG_ITMP2, d);
1262 emit_store_dst(jd, iptr, d);
1265 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1267 #if SIZEOF_VOID_P == 8
1268 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1269 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1270 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1273 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1274 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1275 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1276 M_AND(s1, s2, GET_LOW_REG(d));
1277 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1278 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1279 M_AND(s1, s2, GET_HIGH_REG(d));
1281 emit_store_dst(jd, iptr, d);
1284 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1285 /* sx.val.l = constant */
1287 #if SIZEOF_VOID_P == 8
1288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1289 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1290 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1291 M_AND_IMM(s1, iptr->sx.val.l, d);
1293 LCONST(REG_ITMP2, iptr->sx.val.l);
1294 M_AND(s1, REG_ITMP2, d);
1297 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1298 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1299 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1300 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1301 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1304 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1305 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1306 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1307 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1308 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1311 emit_store_dst(jd, iptr, d);
1314 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1316 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1317 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1318 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1320 emit_store_dst(jd, iptr, d);
1323 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1324 /* sx.val.i = constant */
1326 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1327 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1328 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1329 M_OR_IMM(s1, iptr->sx.val.i, d);
1331 ICONST(REG_ITMP2, iptr->sx.val.i);
1332 M_OR(s1, REG_ITMP2, d);
1334 emit_store_dst(jd, iptr, d);
1337 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1339 #if SIZEOF_VOID_P == 8
1340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1342 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1345 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1346 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1347 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1348 M_OR(s1, s2, GET_LOW_REG(d));
1349 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1350 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1351 M_OR(s1, s2, GET_HIGH_REG(d));
1353 emit_store_dst(jd, iptr, d);
1356 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1357 /* sx.val.l = constant */
1359 #if SIZEOF_VOID_P == 8
1360 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1361 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1362 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1363 M_OR_IMM(s1, iptr->sx.val.l, d);
1365 LCONST(REG_ITMP2, iptr->sx.val.l);
1366 M_OR(s1, REG_ITMP2, d);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1370 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1371 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1372 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1373 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1376 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1377 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1378 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1379 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1380 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1383 emit_store_dst(jd, iptr, d);
1386 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1388 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1389 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1390 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1392 emit_store_dst(jd, iptr, d);
1395 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1396 /* sx.val.i = constant */
1398 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1400 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1401 M_XOR_IMM(s1, iptr->sx.val.i, d);
1403 ICONST(REG_ITMP2, iptr->sx.val.i);
1404 M_XOR(s1, REG_ITMP2, d);
1406 emit_store_dst(jd, iptr, d);
1409 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1411 #if SIZEOF_VOID_P == 8
1412 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1413 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1414 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1417 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1418 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1419 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1420 M_XOR(s1, s2, GET_LOW_REG(d));
1421 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1422 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1423 M_XOR(s1, s2, GET_HIGH_REG(d));
1425 emit_store_dst(jd, iptr, d);
1428 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1429 /* sx.val.l = constant */
1431 #if SIZEOF_VOID_P == 8
1432 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1433 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1434 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1435 M_XOR_IMM(s1, iptr->sx.val.l, d);
1437 LCONST(REG_ITMP2, iptr->sx.val.l);
1438 M_XOR(s1, REG_ITMP2, d);
1441 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1442 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1443 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1444 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1445 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1448 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1449 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1450 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1451 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1452 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1455 emit_store_dst(jd, iptr, d);
1459 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1461 #if SIZEOF_VOID_P == 8
1462 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1463 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1464 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1465 M_CMPLT(s1, s2, REG_ITMP3);
1466 M_CMPLT(s2, s1, REG_ITMP1);
1467 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1469 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1470 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1472 M_CMPLT(s1, s2, REG_ITMP3);
1473 M_CMPLT(s2, s1, REG_ITMP1);
1474 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1477 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1478 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1479 M_CMPULT(s1, s2, REG_ITMP3);
1480 M_CMPULT(s2, s1, REG_ITMP1);
1481 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1483 emit_store_dst(jd, iptr, d);
1487 /* floating operations ************************************************/
1489 case ICMD_FNEG: /* ..., value ==> ..., - value */
1491 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1492 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1494 emit_store_dst(jd, iptr, d);
1497 case ICMD_DNEG: /* ..., value ==> ..., - value */
1499 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1500 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1502 emit_store_dst(jd, iptr, d);
1505 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1507 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1508 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1509 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1511 emit_store_dst(jd, iptr, d);
1514 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1516 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1517 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1518 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1520 emit_store_dst(jd, iptr, d);
1523 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1525 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1526 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1527 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1529 emit_store_dst(jd, iptr, d);
1532 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1534 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1535 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1536 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1538 emit_store_dst(jd, iptr, d);
1541 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1543 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1544 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1545 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1547 emit_store_dst(jd, iptr, d);
1550 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1552 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1553 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1554 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1556 emit_store_dst(jd, iptr, d);
1559 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1561 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1562 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1563 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1565 emit_store_dst(jd, iptr, d);
1568 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1570 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1571 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1572 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1574 emit_store_dst(jd, iptr, d);
1578 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1580 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1581 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1582 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1583 M_FDIV(s1,s2, REG_FTMP3);
1584 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1585 M_CVTLF(REG_FTMP3, REG_FTMP3);
1586 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1587 M_FSUB(s1, REG_FTMP3, d);
1588 emit_store_dst(jd, iptr, d);
1591 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1593 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1594 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1595 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1596 M_DDIV(s1,s2, REG_FTMP3);
1597 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1598 M_CVTLD(REG_FTMP3, REG_FTMP3);
1599 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1600 M_DSUB(s1, REG_FTMP3, d);
1601 emit_store_dst(jd, iptr, d);
1605 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1608 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1611 emit_store_dst(jd, iptr, d);
1614 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1616 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1617 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1620 emit_store_dst(jd, iptr, d);
1624 /* XXX these do not work correctly */
1626 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1628 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1630 M_TRUNCFI(s1, REG_FTMP1);
1631 M_MOVDI(REG_FTMP1, d);
1633 emit_store_dst(jd, iptr, d);
1636 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1638 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1640 M_TRUNCDI(s1, REG_FTMP1);
1641 M_MOVDI(REG_FTMP1, d);
1643 emit_store_dst(jd, iptr, d);
1646 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1648 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1649 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1650 M_TRUNCFL(s1, REG_FTMP1);
1651 M_MOVDL(REG_FTMP1, d);
1653 emit_store_dst(jd, iptr, d);
1656 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1658 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1659 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1660 M_TRUNCDL(s1, REG_FTMP1);
1661 M_MOVDL(REG_FTMP1, d);
1663 emit_store_dst(jd, iptr, d);
1667 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1669 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1670 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1672 emit_store_dst(jd, iptr, d);
1675 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1677 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1678 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1680 emit_store_dst(jd, iptr, d);
1683 #if SUPPORT_FLOAT_CMP
1684 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1686 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1687 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1688 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1691 M_AADD_IMM(REG_ZERO, 1, d);
1695 M_ASUB_IMM(REG_ZERO, 1, d);
1696 M_CMOVT(REG_ZERO, d);
1697 emit_store_dst(jd, iptr, d);
1700 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1702 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1703 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1707 M_ASUB_IMM(REG_ZERO, 1, d);
1711 M_AADD_IMM(REG_ZERO, 1, d);
1712 M_CMOVT(REG_ZERO, d);
1713 emit_store_dst(jd, iptr, d);
1717 #if SUPPORT_DOUBLE_CMP
1718 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1720 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1721 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1722 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1725 M_AADD_IMM(REG_ZERO, 1, d);
1729 M_ASUB_IMM(REG_ZERO, 1, d);
1730 M_CMOVT(REG_ZERO, d);
1731 emit_store_dst(jd, iptr, d);
1734 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1736 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1737 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1738 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1741 M_ASUB_IMM(REG_ZERO, 1, d);
1745 M_AADD_IMM(REG_ZERO, 1, d);
1746 M_CMOVT(REG_ZERO, d);
1747 emit_store_dst(jd, iptr, d);
1752 /* memory operations **************************************************/
1754 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1757 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1758 /* implicit null-pointer check */
1759 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1760 emit_store_dst(jd, iptr, d);
1763 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1768 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1769 M_AADD(s2, s1, REG_ITMP3);
1770 /* implicit null-pointer check */
1771 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1772 emit_store_dst(jd, iptr, d);
1775 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1777 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1778 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1779 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1780 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1781 M_AADD(s2, s1, REG_ITMP3);
1782 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1783 /* implicit null-pointer check */
1784 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1785 emit_store_dst(jd, iptr, d);
1788 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1793 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1794 M_AADD(s2, s1, REG_ITMP3);
1795 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1796 /* implicit null-pointer check */
1797 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1798 emit_store_dst(jd, iptr, d);
1801 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1804 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1805 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1806 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1807 M_ASLL_IMM(s2, 2, REG_ITMP3);
1808 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1809 /* implicit null-pointer check */
1810 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1811 emit_store_dst(jd, iptr, d);
1814 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1817 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1818 #if SIZEOF_VOID_P == 8
1819 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1823 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1824 M_ASLL_IMM(s2, 3, REG_ITMP3);
1825 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1826 /* implicit null-pointer check */
1827 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1828 emit_store_dst(jd, iptr, d);
1831 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1833 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1834 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1835 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1836 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1837 M_ASLL_IMM(s2, 2, REG_ITMP3);
1838 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1839 /* implicit null-pointer check */
1840 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1841 emit_store_dst(jd, iptr, d);
1844 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1846 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1847 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1848 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1849 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1850 M_ASLL_IMM(s2, 3, REG_ITMP3);
1851 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1852 /* implicit null-pointer check */
1853 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1854 emit_store_dst(jd, iptr, d);
1857 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1861 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1862 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1863 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1864 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1865 /* implicit null-pointer check */
1866 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1867 emit_store_dst(jd, iptr, d);
1871 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1873 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1874 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1875 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1876 M_AADD(s2, s1, REG_ITMP1);
1877 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1878 /* implicit null-pointer check */
1879 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1882 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1883 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1886 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1887 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1888 M_AADD(s2, s1, REG_ITMP1);
1889 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1890 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1891 /* implicit null-pointer check */
1892 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1895 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1897 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1898 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1899 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1900 M_ASLL_IMM(s2, 2, REG_ITMP2);
1901 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1902 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1903 /* implicit null-pointer check */
1904 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1907 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1910 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1911 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1912 M_ASLL_IMM(s2, 3, REG_ITMP2);
1913 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1914 #if SIZEOF_VOID_P == 8
1915 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1917 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1919 /* implicit null-pointer check */
1920 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1923 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1926 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1927 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1928 M_ASLL_IMM(s2, 2, REG_ITMP2);
1929 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1930 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1931 /* implicit null-pointer check */
1932 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1935 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1937 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1938 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1939 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1940 M_ASLL_IMM(s2, 3, REG_ITMP2);
1941 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1942 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1943 /* implicit null-pointer check */
1944 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1948 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1951 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1952 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1953 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1955 M_INTMOVE(s1, REG_A0);
1956 M_INTMOVE(s3, REG_A1);
1957 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1958 M_ALD(REG_ITMP3, REG_PV, disp);
1959 M_JSR(REG_RA, REG_ITMP3);
1961 emit_exception_check(cd, iptr);
1963 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1964 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1965 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1966 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1967 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1968 /* implicit null-pointer check */
1969 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1973 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1975 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1976 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1977 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1978 M_AADD(s2, s1, REG_ITMP1);
1979 /* implicit null-pointer check */
1980 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1983 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1984 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1986 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1987 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1988 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1989 M_AADD(s2, s1, REG_ITMP1);
1990 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1991 /* implicit null-pointer check */
1992 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1995 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1999 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2000 M_ASLL_IMM(s2, 2, REG_ITMP2);
2001 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2002 /* implicit null-pointer check */
2003 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
2006 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2010 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2011 M_ASLL_IMM(s2, 3, REG_ITMP2);
2012 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2013 /* implicit null-pointer check */
2014 #if SIZEOF_VOID_P == 8
2015 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2017 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
2021 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2024 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2025 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
2026 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
2027 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2028 /* implicit null-pointer check */
2029 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2033 case ICMD_GETSTATIC: /* ... ==> ..., value */
2035 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2036 uf = iptr->sx.s23.s3.uf;
2037 fieldtype = uf->fieldref->parseddesc.fd->type;
2038 disp = dseg_add_unique_address(cd, uf);
2040 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2043 fi = iptr->sx.s23.s3.fmiref->p.field;
2044 fieldtype = fi->type;
2045 disp = dseg_add_address(cd, &(fi->value));
2047 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2048 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2051 M_ALD(REG_ITMP1, REG_PV, disp);
2053 switch (fieldtype) {
2055 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2056 M_ILD_INTERN(d, REG_ITMP1, 0);
2059 #if SIZEOF_VOID_P == 8
2060 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2062 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2064 M_LLD_INTERN(d, REG_ITMP1, 0);
2067 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2068 M_ALD_INTERN(d, REG_ITMP1, 0);
2071 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2072 M_FLD_INTERN(d, REG_ITMP1, 0);
2075 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2076 M_DLD_INTERN(d, REG_ITMP1, 0);
2079 emit_store_dst(jd, iptr, d);
2082 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2084 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2085 uf = iptr->sx.s23.s3.uf;
2086 fieldtype = uf->fieldref->parseddesc.fd->type;
2087 disp = dseg_add_unique_address(cd, uf);
2089 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2092 fi = iptr->sx.s23.s3.fmiref->p.field;
2093 fieldtype = fi->type;
2094 disp = dseg_add_address(cd, &(fi->value));
2096 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2097 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2100 M_ALD(REG_ITMP1, REG_PV, disp);
2102 switch (fieldtype) {
2104 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2105 M_IST_INTERN(s1, REG_ITMP1, 0);
2108 #if SIZEOF_VOID_P == 8
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2111 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2113 M_LST_INTERN(s1, REG_ITMP1, 0);
2116 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2117 M_AST_INTERN(s1, REG_ITMP1, 0);
2120 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2121 M_FST_INTERN(s1, REG_ITMP1, 0);
2124 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2125 M_DST_INTERN(s1, REG_ITMP1, 0);
2130 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2131 /* val = value (in current instruction) */
2132 /* following NOP) */
2134 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2135 uf = iptr->sx.s23.s3.uf;
2136 fieldtype = uf->fieldref->parseddesc.fd->type;
2137 disp = dseg_add_unique_address(cd, uf);
2139 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2142 fi = iptr->sx.s23.s3.fmiref->p.field;
2143 fieldtype = fi->type;
2144 disp = dseg_add_address(cd, &(fi->value));
2146 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2147 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2150 M_ALD(REG_ITMP1, REG_PV, disp);
2152 switch (fieldtype) {
2154 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2157 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2160 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2163 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2166 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2172 case ICMD_GETFIELD: /* ... ==> ..., value */
2174 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2175 emit_nullpointer_check(cd, iptr, s1);
2177 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2178 uf = iptr->sx.s23.s3.uf;
2179 fieldtype = uf->fieldref->parseddesc.fd->type;
2182 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2185 fi = iptr->sx.s23.s3.fmiref->p.field;
2186 fieldtype = fi->type;
2190 switch (fieldtype) {
2192 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2196 #if SIZEOF_VOID_P == 8
2197 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2200 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2201 M_LLD_GETFIELD(d, s1, disp);
2205 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2209 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2213 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2217 emit_store_dst(jd, iptr, d);
2220 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2223 emit_nullpointer_check(cd, iptr, s1);
2225 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2226 uf = iptr->sx.s23.s3.uf;
2227 fieldtype = uf->fieldref->parseddesc.fd->type;
2231 fi = iptr->sx.s23.s3.fmiref->p.field;
2232 fieldtype = fi->type;
2236 #if SIZEOF_VOID_P == 8
2237 if (IS_INT_LNG_TYPE(fieldtype))
2238 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2240 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2242 if (IS_INT_LNG_TYPE(fieldtype)) {
2243 if (IS_2_WORD_TYPE(fieldtype))
2244 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2246 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2249 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2252 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2253 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2255 switch (fieldtype) {
2257 M_IST(s2, s1, disp);
2260 M_LST(s2, s1, disp);
2263 M_AST(s2, s1, disp);
2266 M_FST(s2, s1, disp);
2269 M_DST(s2, s1, disp);
2274 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2276 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2277 emit_nullpointer_check(cd, iptr, s1);
2279 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2280 unresolved_field *uf = iptr->sx.s23.s3.uf;
2282 fieldtype = uf->fieldref->parseddesc.fd->type;
2285 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2288 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2289 fieldtype = fi->type;
2293 switch (fieldtype) {
2295 M_IST(REG_ZERO, s1, disp);
2298 M_LST(REG_ZERO, s1, disp);
2301 M_AST(REG_ZERO, s1, disp);
2304 M_FST(REG_ZERO, s1, disp);
2307 M_DST(REG_ZERO, s1, disp);
2313 /* branch operations **************************************************/
2315 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2317 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2318 M_INTMOVE(s1, REG_ITMP1_XPTR);
2320 #ifdef ENABLE_VERIFIER
2321 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2322 uc = iptr->sx.s23.s2.uc;
2324 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2326 #endif /* ENABLE_VERIFIER */
2328 disp = dseg_add_functionptr(cd, asm_handle_exception);
2329 M_ALD(REG_ITMP2, REG_PV, disp);
2330 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2332 M_NOP; /* nop ensures that XPC is less than the end */
2333 /* of basic block */
2337 case ICMD_GOTO: /* ... ==> ... */
2338 case ICMD_RET: /* ... ==> ... */
2340 emit_br(cd, iptr->dst.block);
2344 case ICMD_JSR: /* ... ==> ... */
2346 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2350 case ICMD_IFNULL: /* ..., value ==> ... */
2351 case ICMD_IFNONNULL:
2353 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2354 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2357 case ICMD_IFEQ: /* ..., value ==> ... */
2359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2360 if (iptr->sx.val.i == 0)
2361 emit_beqz(cd, iptr->dst.block, s1);
2363 ICONST(REG_ITMP2, iptr->sx.val.i);
2364 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2368 case ICMD_IFLT: /* ..., value ==> ... */
2370 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2371 if (iptr->sx.val.i == 0)
2372 emit_bltz(cd, iptr->dst.block, s1);
2374 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2375 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2377 ICONST(REG_ITMP2, iptr->sx.val.i);
2378 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2380 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2384 case ICMD_IFLE: /* ..., value ==> ... */
2386 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2387 if (iptr->sx.val.i == 0)
2388 emit_blez(cd, iptr->dst.block, s1);
2390 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2391 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2392 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2395 ICONST(REG_ITMP2, iptr->sx.val.i);
2396 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2397 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2402 case ICMD_IFNE: /* ..., value ==> ... */
2404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2405 if (iptr->sx.val.i == 0)
2406 emit_bnez(cd, iptr->dst.block, s1);
2408 ICONST(REG_ITMP2, iptr->sx.val.i);
2409 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2413 case ICMD_IFGT: /* ..., value ==> ... */
2415 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2416 if (iptr->sx.val.i == 0)
2417 emit_bgtz(cd, iptr->dst.block, s1);
2419 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2420 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2421 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2424 ICONST(REG_ITMP2, iptr->sx.val.i);
2425 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2426 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2431 case ICMD_IFGE: /* ..., value ==> ... */
2433 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2434 if (iptr->sx.val.i == 0)
2435 emit_bgez(cd, iptr->dst.block, s1);
2437 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2438 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2440 ICONST(REG_ITMP2, iptr->sx.val.i);
2441 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2443 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2447 case ICMD_IF_LEQ: /* ..., value ==> ... */
2449 #if SIZEOF_VOID_P == 8
2450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2451 if (iptr->sx.val.l == 0)
2452 emit_beqz(cd, iptr->dst.block, s1);
2454 LCONST(REG_ITMP2, iptr->sx.val.l);
2455 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2458 if (iptr->sx.val.l == 0) {
2459 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2460 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2461 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2464 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2465 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2466 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2467 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2468 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2469 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2470 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2471 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2476 case ICMD_IF_LLT: /* ..., value ==> ... */
2478 #if SIZEOF_VOID_P == 8
2479 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2480 if (iptr->sx.val.l == 0)
2481 emit_bltz(cd, iptr->dst.block, s1);
2483 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2484 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2486 LCONST(REG_ITMP2, iptr->sx.val.l);
2487 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2489 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2492 if (iptr->sx.val.l == 0) {
2493 /* if high word is less than zero, the whole long is too */
2494 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2495 emit_bltz(cd, iptr->dst.block, s1);
2498 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2499 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2500 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2501 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2502 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2503 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2505 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2506 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2507 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2512 case ICMD_IF_LLE: /* ..., value ==> ... */
2514 #if SIZEOF_VOID_P == 8
2515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2516 if (iptr->sx.val.l == 0)
2517 emit_blez(cd, iptr->dst.block, s1);
2519 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2520 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2521 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2524 LCONST(REG_ITMP2, iptr->sx.val.l);
2525 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2526 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2530 if (iptr->sx.val.l == 0) {
2531 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2532 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2534 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2535 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2538 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2539 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2540 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2541 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2542 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2543 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2545 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2546 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2547 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2552 case ICMD_IF_LNE: /* ..., value ==> ... */
2554 #if SIZEOF_VOID_P == 8
2555 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2556 if (iptr->sx.val.l == 0)
2557 emit_bnez(cd, iptr->dst.block, s1);
2559 LCONST(REG_ITMP2, iptr->sx.val.l);
2560 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2563 if (iptr->sx.val.l == 0) {
2564 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2565 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2566 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2569 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2570 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2571 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2572 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2573 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2574 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2575 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2576 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2581 case ICMD_IF_LGT: /* ..., value ==> ... */
2583 #if SIZEOF_VOID_P == 8
2584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2585 if (iptr->sx.val.l == 0)
2586 emit_bgtz(cd, iptr->dst.block, s1);
2588 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2589 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2590 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2593 LCONST(REG_ITMP2, iptr->sx.val.l);
2594 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2595 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2599 if (iptr->sx.val.l == 0) {
2600 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2601 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2602 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2604 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2607 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2608 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2609 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2610 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2611 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2612 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2614 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2615 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2616 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2621 case ICMD_IF_LGE: /* ..., value ==> ... */
2623 #if SIZEOF_VOID_P == 8
2624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2625 if (iptr->sx.val.l == 0)
2626 emit_bgez(cd, iptr->dst.block, s1);
2628 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2629 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2632 LCONST(REG_ITMP2, iptr->sx.val.l);
2633 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2635 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2638 if (iptr->sx.val.l == 0) {
2639 /* if high word is greater equal zero, the whole long is too */
2640 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2641 emit_bgez(cd, iptr->dst.block, s1);
2644 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2645 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2646 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2647 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2648 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2649 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2651 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2652 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2653 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2658 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2659 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2660 #if SIZEOF_VOID_P == 8
2661 case ICMD_IF_LCMPEQ:
2664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2666 emit_beq(cd, iptr->dst.block, s1, s2);
2669 #if SIZEOF_VOID_P == 4
2670 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2671 /* op1 = target JavaVM pc */
2673 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2674 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2675 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2677 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2678 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2679 emit_beq(cd, iptr->dst.block, s1, s2);
2683 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2684 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2685 #if SIZEOF_VOID_P == 8
2686 case ICMD_IF_LCMPNE:
2689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2691 emit_bne(cd, iptr->dst.block, s1, s2);
2694 #if SIZEOF_VOID_P == 4
2695 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2697 /* TODO: could be optimized (XOR or SUB) */
2698 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2699 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2700 emit_bne(cd, iptr->dst.block, s1, s2);
2701 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2702 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2703 emit_bne(cd, iptr->dst.block, s1, s2);
2707 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2708 #if SIZEOF_VOID_P == 8
2709 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2714 M_CMPLT(s1, s2, REG_ITMP3);
2715 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2718 #if SIZEOF_VOID_P == 4
2719 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2721 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2722 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2723 M_CMPLT(s1, s2, REG_ITMP3);
2724 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2725 M_CMPGT(s1, s2, REG_ITMP3);
2726 /* load low-bits before the branch, so we know the distance */
2727 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2728 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2729 M_BNEZ(REG_ITMP3, 4); /* XXX */
2731 M_CMPULT(s1, s2, REG_ITMP3);
2732 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2736 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2737 #if SIZEOF_VOID_P == 8
2738 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2741 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2742 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2743 M_CMPGT(s1, s2, REG_ITMP3);
2744 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2747 #if SIZEOF_VOID_P == 4
2748 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2750 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2751 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2752 M_CMPGT(s1, s2, REG_ITMP3);
2753 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2754 M_CMPLT(s1, s2, REG_ITMP3);
2755 /* load low-bits before the branch, so we know the distance */
2756 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2757 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2758 M_BNEZ(REG_ITMP3, 4); /* XXX */
2760 M_CMPUGT(s1, s2, REG_ITMP3);
2761 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2765 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2766 #if SIZEOF_VOID_P == 8
2767 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2771 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2772 M_CMPGT(s1, s2, REG_ITMP3);
2773 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2776 #if SIZEOF_VOID_P == 4
2777 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2779 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2780 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2781 M_CMPLT(s1, s2, REG_ITMP3);
2782 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2783 M_CMPGT(s1, s2, REG_ITMP3);
2784 /* load low-bits before the branch, so we know the distance */
2785 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2786 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2787 M_BNEZ(REG_ITMP3, 4); /* XXX */
2789 M_CMPUGT(s1, s2, REG_ITMP3);
2790 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2794 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2795 #if SIZEOF_VOID_P == 8
2796 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2799 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2800 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2801 M_CMPLT(s1, s2, REG_ITMP3);
2802 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2805 #if SIZEOF_VOID_P == 4
2806 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2808 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2809 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2810 M_CMPGT(s1, s2, REG_ITMP3);
2811 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2812 M_CMPLT(s1, s2, REG_ITMP3);
2813 /* load low-bits before the branch, so we know the distance */
2814 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2815 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2816 M_BNEZ(REG_ITMP3, 4); /* XXX */
2818 M_CMPULT(s1, s2, REG_ITMP3);
2819 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2823 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2824 #if SIZEOF_VOID_P == 8
2828 REPLACEMENT_POINT_RETURN(cd, iptr);
2829 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2830 M_INTMOVE(s1, REG_RESULT);
2831 goto nowperformreturn;
2833 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2835 REPLACEMENT_POINT_RETURN(cd, iptr);
2836 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2837 M_INTMOVE(s1, REG_RESULT);
2839 #ifdef ENABLE_VERIFIER
2840 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2841 uc = iptr->sx.s23.s2.uc;
2843 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2845 #endif /* ENABLE_VERIFIER */
2846 goto nowperformreturn;
2848 #if SIZEOF_VOID_P == 4
2849 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2851 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2852 M_LNGMOVE(s1, REG_RESULT_PACKED);
2853 goto nowperformreturn;
2856 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2857 REPLACEMENT_POINT_RETURN(cd, iptr);
2858 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2859 M_FLTMOVE(s1, REG_FRESULT);
2860 goto nowperformreturn;
2862 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2864 REPLACEMENT_POINT_RETURN(cd, iptr);
2865 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2866 M_DBLMOVE(s1, REG_FRESULT);
2867 goto nowperformreturn;
2869 case ICMD_RETURN: /* ... ==> ... */
2871 REPLACEMENT_POINT_RETURN(cd, iptr);
2877 p = cd->stackframesize;
2879 #if !defined(NDEBUG)
2880 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2881 emit_verbosecall_exit(jd);
2884 #if defined(ENABLE_THREADS)
2885 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2886 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2887 M_ALD(REG_ITMP3, REG_PV, disp);
2889 /* we need to save the proper return value */
2891 switch (iptr->opc) {
2894 #if SIZEOF_VOID_P == 8
2897 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2898 M_JSR(REG_RA, REG_ITMP3);
2899 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2901 #if SIZEOF_VOID_P == 4
2903 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2904 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2905 M_JSR(REG_RA, REG_ITMP3);
2911 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2912 M_JSR(REG_RA, REG_ITMP3);
2913 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2916 M_JSR(REG_RA, REG_ITMP3);
2917 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2921 /* and now restore the proper return value */
2923 switch (iptr->opc) {
2926 #if SIZEOF_VOID_P == 8
2929 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2931 #if SIZEOF_VOID_P == 4
2933 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2938 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2944 /* restore return address */
2946 if (!jd->isleafmethod) {
2947 p--; M_ALD(REG_RA, REG_SP, p * 8);
2950 /* restore saved registers */
2952 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2953 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2955 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2956 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2959 /* deallocate stack and return */
2961 if (cd->stackframesize) {
2964 disp = cd->stackframesize * 8;
2965 lo = (short) (disp);
2966 hi = (short) (((disp) - lo) >> 16);
2970 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2972 M_LUI(REG_ITMP3,hi);
2973 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2975 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2988 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2991 branch_target_t *table;
2993 table = iptr->dst.table;
2995 l = iptr->sx.s23.s2.tablelow;
2996 i = iptr->sx.s23.s3.tablehigh;
2998 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3000 {M_INTMOVE(s1, REG_ITMP1);}
3001 else if (l <= 32768) {
3002 M_IADD_IMM(s1, -l, REG_ITMP1);
3005 ICONST(REG_ITMP2, l);
3006 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3009 /* number of targets */
3014 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3015 emit_beqz(cd, table[0].block, REG_ITMP2);
3017 /* build jump table top down and use address of lowest entry */
3022 dseg_add_target(cd, table->block);
3027 /* length of dataseg after last dseg_add_target is used by load */
3029 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
3030 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3031 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3038 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3041 lookup_target_t *lookup;
3043 lookup = iptr->dst.lookup;
3045 i = iptr->sx.s23.s2.lookupcount;
3047 MCODECHECK((i<<2)+8);
3048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3051 ICONST(REG_ITMP2, lookup->value);
3052 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3056 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3062 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3064 bte = iptr->sx.s23.s3.bte;
3068 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3070 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3071 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3072 case ICMD_INVOKEINTERFACE:
3074 REPLACEMENT_POINT_INVOKE(cd, iptr);
3076 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3078 um = iptr->sx.s23.s3.um;
3079 md = um->methodref->parseddesc.md;
3082 lm = iptr->sx.s23.s3.fmiref->p.method;
3084 md = lm->parseddesc;
3088 s3 = md->paramcount;
3090 MCODECHECK((s3 << 1) + 64);
3092 /* copy arguments to registers or stack location */
3094 for (s3 = s3 - 1; s3 >= 0; s3--) {
3095 var = VAR(iptr->sx.s23.s2.args[s3]);
3097 if (var->flags & PREALLOC)
3100 if (IS_INT_LNG_TYPE(var->type)) {
3101 #if SIZEOF_VOID_P == 8
3102 if (!md->params[s3].inmemory) {
3103 s1 = rd->argintregs[md->params[s3].regoff];
3104 d = emit_load(jd, iptr, var, s1);
3108 d = emit_load(jd, iptr, var, REG_ITMP1);
3109 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3112 if (!md->params[s3].inmemory) {
3113 if (IS_2_WORD_TYPE(var->type)) {
3114 s1 = md->params[s3].regoff;
3115 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3116 rd->argintregs[GET_HIGH_REG(s1)]);
3117 d = emit_load(jd, iptr, var, s1);
3121 s1 = rd->argintregs[md->params[s3].regoff];
3122 d = emit_load(jd, iptr, var, s1);
3127 if (IS_2_WORD_TYPE(var->type)) {
3128 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3129 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3132 d = emit_load(jd, iptr, var, REG_ITMP1);
3133 M_IST(d, REG_SP, md->params[s3].regoff * 8);
3139 if (!md->params[s3].inmemory) {
3140 #if SIZEOF_VOID_P == 8
3141 s1 = rd->argfltregs[md->params[s3].regoff];
3142 d = emit_load(jd, iptr, var, s1);
3143 if (IS_2_WORD_TYPE(var->type))
3149 ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
3150 s1 = rd->argfltregs[md->params[s3].regoff];
3151 d = emit_load(jd, iptr, var, s1);
3152 if (IS_2_WORD_TYPE(var->type))
3158 if (IS_2_WORD_TYPE(var->type)) {
3159 s1 = md->params[s3].regoff;
3160 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3161 rd->argintregs[GET_HIGH_REG(s1)]);
3162 d = emit_load(jd, iptr, var, REG_FTMP1);
3163 M_MFC1(GET_LOW_REG(s2), d);
3164 M_MFC1(GET_HIGH_REG(s2), d + 1);
3168 s1 = rd->argintregs[md->params[s3].regoff];
3169 d = emit_load(jd, iptr, var, s1);
3177 d = emit_load(jd, iptr, var, REG_FTMP1);
3178 if (IS_2_WORD_TYPE(var->type))
3179 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3181 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3186 switch (iptr->opc) {
3188 disp = dseg_add_functionptr(cd, bte->fp);
3190 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3192 /* generate the actual call */
3194 /* TWISTI: i actually don't know the reason for using
3195 REG_ITMP3 here instead of REG_PV. */
3197 M_JSR(REG_RA, REG_ITMP3);
3199 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3200 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3201 M_LDA(REG_PV, REG_RA, -disp);
3203 emit_exception_check(cd, iptr);
3206 case ICMD_INVOKESPECIAL:
3207 emit_nullpointer_check(cd, iptr, REG_A0);
3210 case ICMD_INVOKESTATIC:
3212 disp = dseg_add_unique_address(cd, um);
3214 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
3218 disp = dseg_add_address(cd, lm->stubroutine);
3220 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3222 /* generate the actual call */
3224 M_JSR(REG_RA, REG_PV);
3226 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3227 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3228 M_LDA(REG_PV, REG_RA, -disp);
3231 case ICMD_INVOKEVIRTUAL:
3232 emit_nullpointer_check(cd, iptr, REG_A0);
3235 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
3240 s1 = OFFSET(vftbl_t, table[0]) +
3241 sizeof(methodptr) * lm->vftblindex;
3243 /* implicit null-pointer check */
3244 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3245 M_ALD(REG_PV, REG_METHODPTR, s1);
3247 /* generate the actual call */
3249 M_JSR(REG_RA, REG_PV);
3251 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3252 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3253 M_LDA(REG_PV, REG_RA, -disp);
3256 case ICMD_INVOKEINTERFACE:
3257 emit_nullpointer_check(cd, iptr, REG_A0);
3260 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
3266 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3267 sizeof(methodptr*) * lm->class->index;
3269 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3272 /* implicit null-pointer check */
3273 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3274 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3275 M_ALD(REG_PV, REG_METHODPTR, s2);
3277 /* generate the actual call */
3279 M_JSR(REG_RA, REG_PV);
3281 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3282 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3283 M_LDA(REG_PV, REG_RA, -disp);
3287 /* store return value */
3289 d = md->returntype.type;
3291 if (d != TYPE_VOID) {
3292 if (IS_INT_LNG_TYPE(d)) {
3293 #if SIZEOF_VOID_P == 8
3294 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3295 M_INTMOVE(REG_RESULT, s1);
3297 if (IS_2_WORD_TYPE(d)) {
3298 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3299 M_LNGMOVE(REG_RESULT_PACKED, s1);
3302 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3303 M_INTMOVE(REG_RESULT, s1);
3308 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3309 if (IS_2_WORD_TYPE(d))
3310 M_DMOV(REG_FRESULT, s1);
3312 M_FMOV(REG_FRESULT, s1);
3314 emit_store_dst(jd, iptr, s1);
3319 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3320 /* val.a: (classinfo*) superclass */
3322 /* superclass is an interface:
3324 * OK if ((sub == NULL) ||
3325 * (sub->vftbl->interfacetablelength > super->index) &&
3326 * (sub->vftbl->interfacetable[-super->index] != NULL));
3328 * superclass is a class:
3330 * OK if ((sub == NULL) || (0
3331 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3332 * super->vftbl->diffvall));
3335 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3339 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3344 super = iptr->sx.s23.s3.c.cls;
3345 superindex = super->index;
3348 #if defined(ENABLE_THREADS)
3349 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3354 /* if class is not resolved, check which code to call */
3356 if (super == NULL) {
3357 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3359 cr = iptr->sx.s23.s3.c.ref;
3360 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3362 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3365 M_ILD(REG_ITMP2, REG_PV, disp);
3366 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3367 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3370 /* interface checkcast code */
3372 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3373 if (super == NULL) {
3374 cr = iptr->sx.s23.s3.c.ref;
3376 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3380 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3383 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3384 M_ILD(REG_ITMP3, REG_ITMP2,
3385 OFFSET(vftbl_t, interfacetablelength));
3386 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3387 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3389 M_ALD(REG_ITMP3, REG_ITMP2,
3390 OFFSET(vftbl_t, interfacetable[0]) -
3391 superindex * sizeof(methodptr*));
3392 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3395 emit_label_br(cd, BRANCH_LABEL_4);
3397 emit_label(cd, BRANCH_LABEL_3);
3400 /* class checkcast code */
3402 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3403 if (super == NULL) {
3404 emit_label(cd, BRANCH_LABEL_2);
3406 cr = iptr->sx.s23.s3.c.ref;
3407 disp = dseg_add_unique_address(cd, NULL);
3409 codegen_add_patch_ref(cd,
3410 PATCHER_checkcast_instanceof_class,
3414 disp = dseg_add_address(cd, super->vftbl);
3416 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3419 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3420 M_ALD(REG_ITMP3, REG_PV, disp);
3421 #if defined(ENABLE_THREADS)
3422 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3424 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3425 /* if (s1 != REG_ITMP1) { */
3426 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3427 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3428 /* #if defined(ENABLE_THREADS) */
3429 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3431 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3433 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3434 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3435 M_ALD(REG_ITMP3, REG_PV, disp);
3436 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3437 #if defined(ENABLE_THREADS)
3438 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3441 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3442 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3445 emit_label(cd, BRANCH_LABEL_5);
3448 if (super == NULL) {
3449 emit_label(cd, BRANCH_LABEL_1);
3450 emit_label(cd, BRANCH_LABEL_4);
3453 d = codegen_reg_of_dst(jd, iptr, s1);
3456 s1 = emit_load_s1(jd, iptr, REG_A0);
3457 M_INTMOVE(s1, REG_A0);
3459 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3460 cr = iptr->sx.s23.s3.c.ref;
3461 disp = dseg_add_unique_address(cd, NULL);
3463 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3467 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3469 M_ALD(REG_A1, REG_PV, disp);
3470 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3471 M_ALD(REG_ITMP3, REG_PV, disp);
3472 M_JSR(REG_RA, REG_ITMP3);
3475 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3476 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3478 d = codegen_reg_of_dst(jd, iptr, s1);
3482 emit_store_dst(jd, iptr, d);
3485 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3486 /* val.a: (classinfo*) superclass */
3488 /* superclass is an interface:
3490 * return (sub != NULL) &&
3491 * (sub->vftbl->interfacetablelength > super->index) &&
3492 * (sub->vftbl->interfacetable[-super->index] != NULL);
3494 * superclass is a class:
3496 * return ((sub != NULL) && (0
3497 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3498 * super->vftbl->diffvall));
3505 super = iptr->sx.s23.s3.c.cls;
3507 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3512 super = iptr->sx.s23.s3.c.cls;
3513 superindex = super->index;
3516 #if defined(ENABLE_THREADS)
3517 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3524 M_MOV(s1, REG_ITMP1);
3530 /* if class is not resolved, check which code to call */
3532 if (super == NULL) {
3533 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3535 cr = iptr->sx.s23.s3.c.ref;
3536 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3538 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3541 M_ILD(REG_ITMP3, REG_PV, disp);
3542 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3543 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3546 /* interface instanceof code */
3548 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3549 if (super == NULL) {
3550 cr = iptr->sx.s23.s3.c.ref;
3552 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3556 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3559 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3560 M_ILD(REG_ITMP3, REG_ITMP1,
3561 OFFSET(vftbl_t, interfacetablelength));
3562 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3563 M_BLEZ(REG_ITMP3, 3);
3565 M_ALD(REG_ITMP1, REG_ITMP1,
3566 OFFSET(vftbl_t, interfacetable[0]) -
3567 superindex * sizeof(methodptr*));
3568 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3571 emit_label_br(cd, BRANCH_LABEL_4);
3573 emit_label(cd, BRANCH_LABEL_3);
3576 /* class instanceof code */
3578 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3579 if (super == NULL) {
3580 emit_label(cd, BRANCH_LABEL_2);
3582 cr = iptr->sx.s23.s3.c.ref;
3583 disp = dseg_add_unique_address(cd, NULL);
3585 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3589 disp = dseg_add_address(cd, super->vftbl);
3591 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3594 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3595 M_ALD(REG_ITMP2, REG_PV, disp);
3596 #if defined(ENABLE_THREADS)
3597 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3599 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3600 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3601 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3602 #if defined(ENABLE_THREADS)
3603 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3605 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3606 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3610 emit_label(cd, BRANCH_LABEL_5);
3613 if (super == NULL) {
3614 emit_label(cd, BRANCH_LABEL_1);
3615 emit_label(cd, BRANCH_LABEL_4);
3618 emit_store_dst(jd, iptr, d);
3622 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3624 /* check for negative sizes and copy sizes to stack if necessary */
3626 MCODECHECK((iptr->s1.argcount << 1) + 64);
3628 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3630 var = VAR(iptr->sx.s23.s2.args[s1]);
3632 /* copy SAVEDVAR sizes to stack */
3634 if (!(var->flags & PREALLOC)) {
3635 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3636 #if SIZEOF_VOID_P == 8
3637 M_LST(s2, REG_SP, s1 * 8);
3639 M_IST(s2, REG_SP, (s1 + 2) * 8);
3644 /* a0 = dimension count */
3646 ICONST(REG_A0, iptr->s1.argcount);
3648 /* is patcher function set? */
3650 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3651 cr = iptr->sx.s23.s3.c.ref;
3652 disp = dseg_add_unique_address(cd, NULL);
3654 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3658 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3660 /* a1 = arraydescriptor */
3662 M_ALD(REG_A1, REG_PV, disp);
3664 /* a2 = pointer to dimensions = stack pointer */
3666 #if SIZEOF_VOID_P == 8
3667 M_MOV(REG_SP, REG_A2);
3669 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3672 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3673 M_ALD(REG_ITMP3, REG_PV, disp);
3674 M_JSR(REG_RA, REG_ITMP3);
3677 /* check for exception before result assignment */
3679 emit_exception_check(cd, iptr);
3681 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3682 M_INTMOVE(REG_RESULT, d);
3683 emit_store_dst(jd, iptr, d);
3687 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3692 } /* for instruction */
3694 MCODECHECK(64); /* XXX require smaller number? */
3696 /* At the end of a basic block we may have to append some nops,
3697 because the patcher stub calling code might be longer than the
3698 actual instruction. So codepatching does not change the
3699 following block unintentionally. */
3701 if (cd->mcodeptr < cd->lastmcodeptr) {
3702 while (cd->mcodeptr < cd->lastmcodeptr)
3706 } /* if (bptr -> flags >= BBREACHED) */
3707 } /* for basic block */
3709 dseg_createlinenumbertable(cd);
3711 /* generate stubs */
3713 emit_patcher_stubs(jd);
3714 REPLACEMENT_EMIT_STUBS(jd);
3716 /* everything's ok */
3722 /* createcompilerstub **********************************************************
3724 Creates a stub routine which calls the compiler.
3726 *******************************************************************************/
3728 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3729 #define COMPILERSTUB_CODESIZE 4 * 4
3731 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3734 u1 *createcompilerstub(methodinfo *m)
3736 u1 *s; /* memory to hold the stub */
3741 s = CNEW(u1, COMPILERSTUB_SIZE);
3743 /* set data pointer and code pointer */
3746 s = s + COMPILERSTUB_DATASIZE;
3748 /* mark start of dump memory area */
3750 dumpsize = dump_size();
3752 cd = DNEW(codegendata);
3755 /* The codeinfo pointer is actually a pointer to the
3756 methodinfo. This fakes a codeinfo structure. */
3758 d[0] = (ptrint) asm_call_jit_compiler;
3760 d[2] = (ptrint) &d[1]; /* fake code->m */
3762 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3763 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3767 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3769 #if defined(ENABLE_STATISTICS)
3771 count_cstub_len += COMPILERSTUB_SIZE;
3774 /* release dump area */
3776 dump_release(dumpsize);
3782 /* createnativestub ************************************************************
3784 Creates a stub routine which calls a native method.
3786 *******************************************************************************/
3788 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3796 s4 i, j; /* count variables */
3799 s4 funcdisp; /* displacement of the function */
3801 /* get required compiler data */
3808 /* initialize variables */
3811 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3813 /* calculate stack frame size */
3815 cd->stackframesize =
3816 1 + /* return address */
3817 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3818 sizeof(localref_table) / SIZEOF_VOID_P +
3819 md->paramcount + /* for saving arguments over calls */
3820 #if SIZEOF_VOID_P == 4
3821 5 + /* additional save space (MIPS32) */
3823 1 + /* for saving return address */
3826 /* adjust stackframe size for 16-byte alignment */
3828 if (cd->stackframesize & 1)
3829 cd->stackframesize++;
3831 /* create method header */
3833 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3834 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3835 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3836 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3837 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3838 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3839 (void) dseg_addlinenumbertablesize(cd);
3840 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3842 /* generate stub code */
3844 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3845 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3847 #if !defined(NDEBUG)
3848 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3849 emit_verbosecall_enter(jd);
3852 /* get function address (this must happen before the stackframeinfo) */
3854 funcdisp = dseg_add_functionptr(cd, f);
3856 #if !defined(WITH_STATIC_CLASSPATH)
3858 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3861 /* save integer and float argument registers */
3863 #if SIZEOF_VOID_P == 8
3864 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3865 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3866 M_AST(rd->argintregs[i], REG_SP, j * 8);
3871 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3872 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3873 if (!md->params[i].inmemory) {
3874 s1 = md->params[i].regoff;
3875 if (IS_2_WORD_TYPE(md->params[i].type)) {
3876 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3877 rd->argintregs[GET_HIGH_REG(s1)]);
3878 M_LST(s1, REG_SP, j * 8);
3881 M_IST(rd->argintregs[s1], REG_SP, j * 8);
3889 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3890 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3891 if (IS_2_WORD_TYPE(md->params[i].type))
3892 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3894 M_FST(rd->argfltregs[i], REG_SP, j * 8);
3899 /* prepare data structures for native function call */
3901 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3902 M_MOV(REG_PV, REG_A1);
3903 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3904 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3905 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3906 M_ALD(REG_ITMP3, REG_PV, disp);
3907 M_JSR(REG_RA, REG_ITMP3);
3908 M_NOP; /* XXX fill me! */
3910 /* restore integer and float argument registers */
3912 #if SIZEOF_VOID_P == 8
3913 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3914 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3915 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3920 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3921 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3922 if (!md->params[i].inmemory) {
3923 s1 = md->params[i].regoff;
3924 if (IS_2_WORD_TYPE(md->params[i].type)) {
3925 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3926 rd->argintregs[GET_HIGH_REG(s1)]);
3927 M_LLD(s1, REG_SP, j * 8);
3930 M_ILD(rd->argintregs[s1], REG_SP, j * 8);
3938 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3939 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3940 if (IS_2_WORD_TYPE(md->params[i].type))
3941 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3943 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
3948 /* copy or spill arguments to new locations */
3950 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3951 t = md->params[i].type;
3953 if (IS_INT_LNG_TYPE(t)) {
3954 if (!md->params[i].inmemory) {
3955 s1 = md->params[i].regoff;
3956 #if SIZEOF_VOID_P == 8
3957 s1 = rd->argintregs[s1];
3959 if (IS_2_WORD_TYPE(t))
3960 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3961 rd->argintregs[GET_HIGH_REG(s1)]);
3963 s1 = rd->argintregs[s1];
3966 if (!nmd->params[j].inmemory) {
3967 s2 = nmd->params[j].regoff;
3968 #if SIZEOF_VOID_P == 8
3969 s2 = rd->argintregs[s2];
3972 if (IS_2_WORD_TYPE(t)) {
3973 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
3974 rd->argintregs[GET_HIGH_REG(s2)]);
3978 s2 = rd->argintregs[s2];
3984 s2 = nmd->params[j].regoff;
3986 #if SIZEOF_VOID_P == 8
3987 M_LST(s1, REG_SP, s2 * 8);
3989 if (IS_2_WORD_TYPE(t))
3990 M_LST(s1, REG_SP, s2 * 4);
3992 M_IST(s1, REG_SP, s2 * 4);
3997 s1 = md->params[i].regoff + cd->stackframesize;
3998 s2 = nmd->params[j].regoff;
4000 #if SIZEOF_VOID_P == 8
4001 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4002 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4004 if (IS_2_WORD_TYPE(t)) {
4005 M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8);
4006 M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4);
4009 M_ILD(REG_ITMP1, REG_SP, s1 * 8);
4010 M_IST(REG_ITMP1, REG_SP, s2 * 4);
4016 if (!md->params[i].inmemory) {
4017 s1 = md->params[i].regoff;
4018 s2 = nmd->params[j].regoff;
4020 if (!nmd->params[j].inmemory) {
4021 #if SIZEOF_VOID_P == 8
4022 s1 = rd->argfltregs[s1];
4023 s2 = rd->argfltregs[s2];
4024 if (IS_2_WORD_TYPE(t))
4029 /* On MIPS32 float arguments for native functions
4030 can never be in float argument registers, since
4031 the first argument is _always_ an integer
4032 argument (JNIenv) */
4034 if (IS_2_WORD_TYPE(t)) {
4035 s1 = rd->argfltregs[s1];
4036 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
4037 rd->argintregs[GET_HIGH_REG(s2)]);
4039 /* double high/low order is endian
4040 independent: even numbered holds low
4041 32-bits, odd numbered high 32-bits */
4043 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
4044 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
4047 s1 = rd->argfltregs[s1];
4048 s2 = rd->argintregs[s2];
4054 #if SIZEOF_VOID_P == 8
4055 s1 = rd->argfltregs[s1];
4057 if (IS_2_WORD_TYPE(t))
4058 M_DST(s1, REG_SP, s2 * 8);
4060 M_FST(s1, REG_SP, s2 * 8);
4062 /* s1 may have been originally in 2 int registers,
4063 but was moved out by the native function
4064 argument(s), just get low register */
4066 s1 = rd->argfltregs[GET_LOW_REG(s1)];
4068 if (IS_2_WORD_TYPE(t))
4069 M_DST(s1, REG_SP, s2 * 4);
4071 M_FST(s1, REG_SP, s2 * 4);
4076 s1 = md->params[i].regoff + cd->stackframesize;
4077 s2 = nmd->params[j].regoff;
4079 if (IS_2_WORD_TYPE(t)) {
4080 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4081 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4084 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4085 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4091 /* put class into second argument register */
4093 if (m->flags & ACC_STATIC) {
4094 disp = dseg_add_address(cd, m->class);
4095 M_ALD(REG_A1, REG_PV, disp);
4098 /* put env into first argument register */
4100 disp = dseg_add_address(cd, _Jv_env);
4101 M_ALD(REG_A0, REG_PV, disp);
4103 /* do the native function call */
4105 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4106 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4107 M_NOP; /* delay slot */
4109 /* save return value */
4111 if (md->returntype.type != TYPE_VOID) {
4112 #if SIZEOF_VOID_P == 8
4113 if (IS_INT_LNG_TYPE(md->returntype.type))
4114 M_LST(REG_RESULT, REG_SP, 0 * 8);
4116 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4118 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4119 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4120 if (IS_2_WORD_TYPE(md->returntype.type))
4121 M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4124 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4128 #if !defined(NDEBUG)
4129 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4130 emit_verbosecall_exit(jd);
4133 /* remove native stackframe info */
4135 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
4136 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4137 M_ALD(REG_ITMP3, REG_PV, disp);
4138 M_JSR(REG_RA, REG_ITMP3);
4139 M_NOP; /* XXX fill me! */
4140 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4142 /* restore return value */
4144 if (md->returntype.type != TYPE_VOID) {
4145 #if SIZEOF_VOID_P == 8
4146 if (IS_INT_LNG_TYPE(md->returntype.type))
4147 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4149 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4151 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4152 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4153 if (IS_2_WORD_TYPE(md->returntype.type))
4154 M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4157 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4161 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4163 /* check for exception */
4165 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4166 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4168 M_RET(REG_RA); /* return to caller */
4169 M_NOP; /* DELAY SLOT */
4171 /* handle exception */
4173 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4174 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4175 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4176 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4178 /* generate patcher stubs */
4180 emit_patcher_stubs(jd);
4184 return code->entrypoint;
4189 * These are local overrides for various environment variables in Emacs.
4190 * Please do not remove this and leave it at the end of the file, where
4191 * Emacs will automagically detect them.
4192 * ---------------------------------------------------------------------
4195 * indent-tabs-mode: t
4199 * vim:noexpandtab:sw=4:ts=4: