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 7596 2007-03-28 21:05:53Z 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)
2454 LCONST(REG_ITMP2, iptr->sx.val.l);
2455 M_BEQ(s1, REG_ITMP2, 0);
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) {
2483 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2484 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2486 LCONST(REG_ITMP2, iptr->sx.val.l);
2487 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2489 M_BNEZ(REG_ITMP1, 0);
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) {
2519 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2520 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2521 M_BNEZ(REG_ITMP1, 0);
2523 LCONST(REG_ITMP2, iptr->sx.val.l);
2524 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2525 M_BEQZ(REG_ITMP1, 0);
2529 if (iptr->sx.val.l == 0) {
2530 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2531 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2533 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2534 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2537 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2538 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2539 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2540 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2541 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2542 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2544 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2545 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2546 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2551 case ICMD_IF_LNE: /* ..., value ==> ... */
2553 #if SIZEOF_VOID_P == 8
2554 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2555 if (iptr->sx.val.l == 0) {
2558 LCONST(REG_ITMP2, iptr->sx.val.l);
2559 M_BNE(s1, REG_ITMP2, 0);
2562 if (iptr->sx.val.l == 0) {
2563 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2564 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2565 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2568 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2569 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2570 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2571 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2572 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2573 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2574 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2575 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2580 case ICMD_IF_LGT: /* ..., value ==> ... */
2582 #if SIZEOF_VOID_P == 8
2583 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2584 if (iptr->sx.val.l == 0) {
2587 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2588 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2589 M_BEQZ(REG_ITMP1, 0);
2591 LCONST(REG_ITMP2, iptr->sx.val.l);
2592 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2593 M_BNEZ(REG_ITMP1, 0);
2597 if (iptr->sx.val.l == 0) {
2598 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2599 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2600 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2602 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2605 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2606 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2607 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2608 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2609 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2610 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2612 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2613 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2614 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2619 case ICMD_IF_LGE: /* ..., value ==> ... */
2621 #if SIZEOF_VOID_P == 8
2622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2623 if (iptr->sx.val.l == 0) {
2626 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2627 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2629 LCONST(REG_ITMP2, iptr->sx.val.l);
2630 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2632 M_BEQZ(REG_ITMP1, 0);
2635 if (iptr->sx.val.l == 0) {
2636 /* if high word is greater equal zero, the whole long is too */
2637 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2638 emit_bgez(cd, iptr->dst.block, s1);
2641 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2642 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2643 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2644 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2645 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2646 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2648 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2649 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2650 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2655 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2656 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2657 #if SIZEOF_VOID_P == 8
2658 case ICMD_IF_LCMPEQ:
2661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2662 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2663 emit_beq(cd, iptr->dst.block, s1, s2);
2666 #if SIZEOF_VOID_P == 4
2667 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2668 /* op1 = target JavaVM pc */
2670 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2671 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2672 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2674 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2675 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2676 emit_beq(cd, iptr->dst.block, s1, s2);
2680 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2681 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2682 #if SIZEOF_VOID_P == 8
2683 case ICMD_IF_LCMPNE:
2686 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2687 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2688 emit_bne(cd, iptr->dst.block, s1, s2);
2691 #if SIZEOF_VOID_P == 4
2692 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2694 /* TODO: could be optimized (XOR or SUB) */
2695 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2696 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2697 emit_bne(cd, iptr->dst.block, s1, s2);
2698 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2699 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2700 emit_bne(cd, iptr->dst.block, s1, s2);
2704 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2705 #if SIZEOF_VOID_P == 8
2706 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2709 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2710 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2711 M_CMPLT(s1, s2, REG_ITMP3);
2712 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2715 #if SIZEOF_VOID_P == 4
2716 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2718 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2719 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2720 M_CMPLT(s1, s2, REG_ITMP3);
2721 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2722 M_CMPGT(s1, s2, REG_ITMP3);
2723 /* load low-bits before the branch, so we know the distance */
2724 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2725 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2726 M_BNEZ(REG_ITMP3, 4); /* XXX */
2728 M_CMPULT(s1, s2, REG_ITMP3);
2729 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2733 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2734 #if SIZEOF_VOID_P == 8
2735 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2739 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2740 M_CMPGT(s1, s2, REG_ITMP3);
2741 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2744 #if SIZEOF_VOID_P == 4
2745 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2747 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2748 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2749 M_CMPGT(s1, s2, REG_ITMP3);
2750 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2751 M_CMPLT(s1, s2, REG_ITMP3);
2752 /* load low-bits before the branch, so we know the distance */
2753 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2754 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2755 M_BNEZ(REG_ITMP3, 4); /* XXX */
2757 M_CMPUGT(s1, s2, REG_ITMP3);
2758 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2762 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2763 #if SIZEOF_VOID_P == 8
2764 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2767 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2768 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2769 M_CMPGT(s1, s2, REG_ITMP3);
2770 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2773 #if SIZEOF_VOID_P == 4
2774 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2776 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2777 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2778 M_CMPLT(s1, s2, REG_ITMP3);
2779 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2780 M_CMPGT(s1, s2, REG_ITMP3);
2781 /* load low-bits before the branch, so we know the distance */
2782 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2783 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2784 M_BNEZ(REG_ITMP3, 4); /* XXX */
2786 M_CMPUGT(s1, s2, REG_ITMP3);
2787 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2791 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2792 #if SIZEOF_VOID_P == 8
2793 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2796 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2797 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2798 M_CMPLT(s1, s2, REG_ITMP3);
2799 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2802 #if SIZEOF_VOID_P == 4
2803 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2805 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2806 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2807 M_CMPGT(s1, s2, REG_ITMP3);
2808 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2809 M_CMPLT(s1, s2, REG_ITMP3);
2810 /* load low-bits before the branch, so we know the distance */
2811 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2812 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2813 M_BNEZ(REG_ITMP3, 4); /* XXX */
2815 M_CMPULT(s1, s2, REG_ITMP3);
2816 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2820 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2821 #if SIZEOF_VOID_P == 8
2825 REPLACEMENT_POINT_RETURN(cd, iptr);
2826 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2827 M_INTMOVE(s1, REG_RESULT);
2828 goto nowperformreturn;
2830 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2832 REPLACEMENT_POINT_RETURN(cd, iptr);
2833 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2834 M_INTMOVE(s1, REG_RESULT);
2836 #ifdef ENABLE_VERIFIER
2837 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2838 uc = iptr->sx.s23.s2.uc;
2840 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2842 #endif /* ENABLE_VERIFIER */
2843 goto nowperformreturn;
2845 #if SIZEOF_VOID_P == 4
2846 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2848 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2849 M_LNGMOVE(s1, REG_RESULT_PACKED);
2850 goto nowperformreturn;
2853 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2854 REPLACEMENT_POINT_RETURN(cd, iptr);
2855 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2856 M_FLTMOVE(s1, REG_FRESULT);
2857 goto nowperformreturn;
2859 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2861 REPLACEMENT_POINT_RETURN(cd, iptr);
2862 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2863 M_DBLMOVE(s1, REG_FRESULT);
2864 goto nowperformreturn;
2866 case ICMD_RETURN: /* ... ==> ... */
2868 REPLACEMENT_POINT_RETURN(cd, iptr);
2874 p = cd->stackframesize;
2876 #if !defined(NDEBUG)
2877 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2878 emit_verbosecall_exit(jd);
2881 #if defined(ENABLE_THREADS)
2882 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2883 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2884 M_ALD(REG_ITMP3, REG_PV, disp);
2886 /* we need to save the proper return value */
2888 switch (iptr->opc) {
2891 #if SIZEOF_VOID_P == 8
2894 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2895 M_JSR(REG_RA, REG_ITMP3);
2896 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2898 #if SIZEOF_VOID_P == 4
2900 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2901 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2902 M_JSR(REG_RA, REG_ITMP3);
2908 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2909 M_JSR(REG_RA, REG_ITMP3);
2910 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2913 M_JSR(REG_RA, REG_ITMP3);
2914 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2918 /* and now restore the proper return value */
2920 switch (iptr->opc) {
2923 #if SIZEOF_VOID_P == 8
2926 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2928 #if SIZEOF_VOID_P == 4
2930 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2935 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2941 /* restore return address */
2943 if (!jd->isleafmethod) {
2944 p--; M_ALD(REG_RA, REG_SP, p * 8);
2947 /* restore saved registers */
2949 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2950 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2952 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2953 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2956 /* deallocate stack and return */
2958 if (cd->stackframesize) {
2961 disp = cd->stackframesize * 8;
2962 lo = (short) (disp);
2963 hi = (short) (((disp) - lo) >> 16);
2967 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2969 M_LUI(REG_ITMP3,hi);
2970 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2972 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2985 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2988 branch_target_t *table;
2990 table = iptr->dst.table;
2992 l = iptr->sx.s23.s2.tablelow;
2993 i = iptr->sx.s23.s3.tablehigh;
2995 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2997 {M_INTMOVE(s1, REG_ITMP1);}
2998 else if (l <= 32768) {
2999 M_IADD_IMM(s1, -l, REG_ITMP1);
3002 ICONST(REG_ITMP2, l);
3003 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3006 /* number of targets */
3011 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3012 emit_beqz(cd, table[0].block, REG_ITMP2);
3014 /* build jump table top down and use address of lowest entry */
3019 dseg_add_target(cd, table->block);
3024 /* length of dataseg after last dseg_add_target is used by load */
3026 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
3027 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3028 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3035 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3038 lookup_target_t *lookup;
3040 lookup = iptr->dst.lookup;
3042 i = iptr->sx.s23.s2.lookupcount;
3044 MCODECHECK((i<<2)+8);
3045 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3048 ICONST(REG_ITMP2, lookup->value);
3049 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
3053 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
3059 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3061 bte = iptr->sx.s23.s3.bte;
3065 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3067 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3068 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3069 case ICMD_INVOKEINTERFACE:
3071 REPLACEMENT_POINT_INVOKE(cd, iptr);
3073 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3075 um = iptr->sx.s23.s3.um;
3076 md = um->methodref->parseddesc.md;
3079 lm = iptr->sx.s23.s3.fmiref->p.method;
3081 md = lm->parseddesc;
3085 s3 = md->paramcount;
3087 MCODECHECK((s3 << 1) + 64);
3089 /* copy arguments to registers or stack location */
3091 for (s3 = s3 - 1; s3 >= 0; s3--) {
3092 var = VAR(iptr->sx.s23.s2.args[s3]);
3094 if (var->flags & PREALLOC)
3097 if (IS_INT_LNG_TYPE(var->type)) {
3098 #if SIZEOF_VOID_P == 8
3099 if (!md->params[s3].inmemory) {
3100 s1 = rd->argintregs[md->params[s3].regoff];
3101 d = emit_load(jd, iptr, var, s1);
3105 d = emit_load(jd, iptr, var, REG_ITMP1);
3106 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3109 if (!md->params[s3].inmemory) {
3110 if (IS_2_WORD_TYPE(var->type)) {
3111 s1 = md->params[s3].regoff;
3112 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3113 rd->argintregs[GET_HIGH_REG(s1)]);
3114 d = emit_load(jd, iptr, var, s1);
3118 s1 = rd->argintregs[md->params[s3].regoff];
3119 d = emit_load(jd, iptr, var, s1);
3124 if (IS_2_WORD_TYPE(var->type)) {
3125 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3126 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3129 d = emit_load(jd, iptr, var, REG_ITMP1);
3130 M_IST(d, REG_SP, md->params[s3].regoff * 8);
3136 if (!md->params[s3].inmemory) {
3137 #if SIZEOF_VOID_P == 8
3138 s1 = rd->argfltregs[md->params[s3].regoff];
3139 d = emit_load(jd, iptr, var, s1);
3140 if (IS_2_WORD_TYPE(var->type))
3146 ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
3147 s1 = rd->argfltregs[md->params[s3].regoff];
3148 d = emit_load(jd, iptr, var, s1);
3149 if (IS_2_WORD_TYPE(var->type))
3155 if (IS_2_WORD_TYPE(var->type)) {
3156 s1 = md->params[s3].regoff;
3157 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3158 rd->argintregs[GET_HIGH_REG(s1)]);
3159 d = emit_load(jd, iptr, var, REG_FTMP1);
3160 M_MFC1(GET_LOW_REG(s2), d);
3161 M_MFC1(GET_HIGH_REG(s2), d + 1);
3165 s1 = rd->argintregs[md->params[s3].regoff];
3166 d = emit_load(jd, iptr, var, s1);
3174 d = emit_load(jd, iptr, var, REG_FTMP1);
3175 if (IS_2_WORD_TYPE(var->type))
3176 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3178 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3183 switch (iptr->opc) {
3185 disp = dseg_add_functionptr(cd, bte->fp);
3187 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3189 /* generate the actual call */
3191 /* TWISTI: i actually don't know the reason for using
3192 REG_ITMP3 here instead of REG_PV. */
3194 M_JSR(REG_RA, REG_ITMP3);
3196 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3197 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3198 M_LDA(REG_PV, REG_RA, -disp);
3200 emit_exception_check(cd, iptr);
3203 case ICMD_INVOKESPECIAL:
3204 emit_nullpointer_check(cd, iptr, REG_A0);
3207 case ICMD_INVOKESTATIC:
3209 disp = dseg_add_unique_address(cd, um);
3211 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
3215 disp = dseg_add_address(cd, lm->stubroutine);
3217 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3219 /* generate the actual call */
3221 M_JSR(REG_RA, REG_PV);
3223 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3224 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3225 M_LDA(REG_PV, REG_RA, -disp);
3228 case ICMD_INVOKEVIRTUAL:
3229 emit_nullpointer_check(cd, iptr, REG_A0);
3232 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
3237 s1 = OFFSET(vftbl_t, table[0]) +
3238 sizeof(methodptr) * lm->vftblindex;
3240 /* implicit null-pointer check */
3241 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3242 M_ALD(REG_PV, REG_METHODPTR, s1);
3244 /* generate the actual call */
3246 M_JSR(REG_RA, REG_PV);
3248 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3249 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3250 M_LDA(REG_PV, REG_RA, -disp);
3253 case ICMD_INVOKEINTERFACE:
3254 emit_nullpointer_check(cd, iptr, REG_A0);
3257 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
3263 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3264 sizeof(methodptr*) * lm->class->index;
3266 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3269 /* implicit null-pointer check */
3270 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3271 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3272 M_ALD(REG_PV, REG_METHODPTR, s2);
3274 /* generate the actual call */
3276 M_JSR(REG_RA, REG_PV);
3278 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3279 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3280 M_LDA(REG_PV, REG_RA, -disp);
3284 /* store return value */
3286 d = md->returntype.type;
3288 if (d != TYPE_VOID) {
3289 if (IS_INT_LNG_TYPE(d)) {
3290 #if SIZEOF_VOID_P == 8
3291 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3292 M_INTMOVE(REG_RESULT, s1);
3294 if (IS_2_WORD_TYPE(d)) {
3295 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3296 M_LNGMOVE(REG_RESULT_PACKED, s1);
3299 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3300 M_INTMOVE(REG_RESULT, s1);
3305 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3306 if (IS_2_WORD_TYPE(d))
3307 M_DMOV(REG_FRESULT, s1);
3309 M_FMOV(REG_FRESULT, s1);
3311 emit_store_dst(jd, iptr, s1);
3316 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3317 /* val.a: (classinfo*) superclass */
3319 /* superclass is an interface:
3321 * OK if ((sub == NULL) ||
3322 * (sub->vftbl->interfacetablelength > super->index) &&
3323 * (sub->vftbl->interfacetable[-super->index] != NULL));
3325 * superclass is a class:
3327 * OK if ((sub == NULL) || (0
3328 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3329 * super->vftbl->diffvall));
3332 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3336 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3341 super = iptr->sx.s23.s3.c.cls;
3342 superindex = super->index;
3345 #if defined(ENABLE_THREADS)
3346 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3351 /* if class is not resolved, check which code to call */
3353 if (super == NULL) {
3354 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3356 cr = iptr->sx.s23.s3.c.ref;
3357 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3359 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3362 M_ILD(REG_ITMP2, REG_PV, disp);
3363 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3364 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3367 /* interface checkcast code */
3369 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3370 if (super == NULL) {
3371 cr = iptr->sx.s23.s3.c.ref;
3373 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3377 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3380 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3381 M_ILD(REG_ITMP3, REG_ITMP2,
3382 OFFSET(vftbl_t, interfacetablelength));
3383 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3384 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3386 M_ALD(REG_ITMP3, REG_ITMP2,
3387 OFFSET(vftbl_t, interfacetable[0]) -
3388 superindex * sizeof(methodptr*));
3389 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3392 emit_label_br(cd, BRANCH_LABEL_4);
3394 emit_label(cd, BRANCH_LABEL_3);
3397 /* class checkcast code */
3399 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3400 if (super == NULL) {
3401 emit_label(cd, BRANCH_LABEL_2);
3403 cr = iptr->sx.s23.s3.c.ref;
3404 disp = dseg_add_unique_address(cd, NULL);
3406 codegen_add_patch_ref(cd,
3407 PATCHER_checkcast_instanceof_class,
3411 disp = dseg_add_address(cd, super->vftbl);
3413 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3416 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3417 M_ALD(REG_ITMP3, REG_PV, disp);
3418 #if defined(ENABLE_THREADS)
3419 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3421 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3422 /* if (s1 != REG_ITMP1) { */
3423 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3424 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3425 /* #if defined(ENABLE_THREADS) */
3426 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3428 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3430 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3431 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3432 M_ALD(REG_ITMP3, REG_PV, disp);
3433 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3434 #if defined(ENABLE_THREADS)
3435 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3438 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3439 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3442 emit_label(cd, BRANCH_LABEL_5);
3445 if (super == NULL) {
3446 emit_label(cd, BRANCH_LABEL_1);
3447 emit_label(cd, BRANCH_LABEL_4);
3450 d = codegen_reg_of_dst(jd, iptr, s1);
3453 s1 = emit_load_s1(jd, iptr, REG_A0);
3454 M_INTMOVE(s1, REG_A0);
3456 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3457 cr = iptr->sx.s23.s3.c.ref;
3458 disp = dseg_add_unique_address(cd, NULL);
3460 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3464 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3466 M_ALD(REG_A1, REG_PV, disp);
3467 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3468 M_ALD(REG_ITMP3, REG_PV, disp);
3469 M_JSR(REG_RA, REG_ITMP3);
3472 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3473 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3475 d = codegen_reg_of_dst(jd, iptr, s1);
3479 emit_store_dst(jd, iptr, d);
3482 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3483 /* val.a: (classinfo*) superclass */
3485 /* superclass is an interface:
3487 * return (sub != NULL) &&
3488 * (sub->vftbl->interfacetablelength > super->index) &&
3489 * (sub->vftbl->interfacetable[-super->index] != NULL);
3491 * superclass is a class:
3493 * return ((sub != NULL) && (0
3494 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3495 * super->vftbl->diffvall));
3502 super = iptr->sx.s23.s3.c.cls;
3504 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3509 super = iptr->sx.s23.s3.c.cls;
3510 superindex = super->index;
3513 #if defined(ENABLE_THREADS)
3514 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3517 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3518 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3521 M_MOV(s1, REG_ITMP1);
3527 /* if class is not resolved, check which code to call */
3529 if (super == NULL) {
3530 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3532 cr = iptr->sx.s23.s3.c.ref;
3533 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3535 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3538 M_ILD(REG_ITMP3, REG_PV, disp);
3539 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3540 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3543 /* interface instanceof code */
3545 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3546 if (super == NULL) {
3547 cr = iptr->sx.s23.s3.c.ref;
3549 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3553 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3556 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3557 M_ILD(REG_ITMP3, REG_ITMP1,
3558 OFFSET(vftbl_t, interfacetablelength));
3559 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3560 M_BLEZ(REG_ITMP3, 3);
3562 M_ALD(REG_ITMP1, REG_ITMP1,
3563 OFFSET(vftbl_t, interfacetable[0]) -
3564 superindex * sizeof(methodptr*));
3565 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3568 emit_label_br(cd, BRANCH_LABEL_4);
3570 emit_label(cd, BRANCH_LABEL_3);
3573 /* class instanceof code */
3575 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3576 if (super == NULL) {
3577 emit_label(cd, BRANCH_LABEL_2);
3579 cr = iptr->sx.s23.s3.c.ref;
3580 disp = dseg_add_unique_address(cd, NULL);
3582 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3586 disp = dseg_add_address(cd, super->vftbl);
3588 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3591 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3592 M_ALD(REG_ITMP2, REG_PV, disp);
3593 #if defined(ENABLE_THREADS)
3594 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3596 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3597 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3598 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3599 #if defined(ENABLE_THREADS)
3600 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3602 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3603 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3607 emit_label(cd, BRANCH_LABEL_5);
3610 if (super == NULL) {
3611 emit_label(cd, BRANCH_LABEL_1);
3612 emit_label(cd, BRANCH_LABEL_4);
3615 emit_store_dst(jd, iptr, d);
3619 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3621 /* check for negative sizes and copy sizes to stack if necessary */
3623 MCODECHECK((iptr->s1.argcount << 1) + 64);
3625 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3627 var = VAR(iptr->sx.s23.s2.args[s1]);
3629 /* copy SAVEDVAR sizes to stack */
3631 if (!(var->flags & PREALLOC)) {
3632 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3633 #if SIZEOF_VOID_P == 8
3634 M_LST(s2, REG_SP, s1 * 8);
3636 M_IST(s2, REG_SP, (s1 + 2) * 8);
3641 /* a0 = dimension count */
3643 ICONST(REG_A0, iptr->s1.argcount);
3645 /* is patcher function set? */
3647 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3648 cr = iptr->sx.s23.s3.c.ref;
3649 disp = dseg_add_unique_address(cd, NULL);
3651 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3655 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3657 /* a1 = arraydescriptor */
3659 M_ALD(REG_A1, REG_PV, disp);
3661 /* a2 = pointer to dimensions = stack pointer */
3663 #if SIZEOF_VOID_P == 8
3664 M_MOV(REG_SP, REG_A2);
3666 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3669 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3670 M_ALD(REG_ITMP3, REG_PV, disp);
3671 M_JSR(REG_RA, REG_ITMP3);
3674 /* check for exception before result assignment */
3676 emit_exception_check(cd, iptr);
3678 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3679 M_INTMOVE(REG_RESULT, d);
3680 emit_store_dst(jd, iptr, d);
3684 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3689 } /* for instruction */
3691 MCODECHECK(64); /* XXX require smaller number? */
3693 /* At the end of a basic block we may have to append some nops,
3694 because the patcher stub calling code might be longer than the
3695 actual instruction. So codepatching does not change the
3696 following block unintentionally. */
3698 if (cd->mcodeptr < cd->lastmcodeptr) {
3699 while (cd->mcodeptr < cd->lastmcodeptr)
3703 } /* if (bptr -> flags >= BBREACHED) */
3704 } /* for basic block */
3706 dseg_createlinenumbertable(cd);
3708 /* generate stubs */
3710 emit_patcher_stubs(jd);
3711 REPLACEMENT_EMIT_STUBS(jd);
3713 /* everything's ok */
3719 /* createcompilerstub **********************************************************
3721 Creates a stub routine which calls the compiler.
3723 *******************************************************************************/
3725 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3726 #define COMPILERSTUB_CODESIZE 4 * 4
3728 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3731 u1 *createcompilerstub(methodinfo *m)
3733 u1 *s; /* memory to hold the stub */
3738 s = CNEW(u1, COMPILERSTUB_SIZE);
3740 /* set data pointer and code pointer */
3743 s = s + COMPILERSTUB_DATASIZE;
3745 /* mark start of dump memory area */
3747 dumpsize = dump_size();
3749 cd = DNEW(codegendata);
3752 /* The codeinfo pointer is actually a pointer to the
3753 methodinfo. This fakes a codeinfo structure. */
3755 d[0] = (ptrint) asm_call_jit_compiler;
3757 d[2] = (ptrint) &d[1]; /* fake code->m */
3759 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3760 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3764 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3766 #if defined(ENABLE_STATISTICS)
3768 count_cstub_len += COMPILERSTUB_SIZE;
3771 /* release dump area */
3773 dump_release(dumpsize);
3779 /* createnativestub ************************************************************
3781 Creates a stub routine which calls a native method.
3783 *******************************************************************************/
3785 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3793 s4 i, j; /* count variables */
3796 s4 funcdisp; /* displacement of the function */
3798 /* get required compiler data */
3805 /* initialize variables */
3808 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3810 /* calculate stack frame size */
3812 cd->stackframesize =
3813 1 + /* return address */
3814 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3815 sizeof(localref_table) / SIZEOF_VOID_P +
3816 md->paramcount + /* for saving arguments over calls */
3817 #if SIZEOF_VOID_P == 4
3818 5 + /* additional save space (MIPS32) */
3820 1 + /* for saving return address */
3823 /* adjust stackframe size for 16-byte alignment */
3825 if (cd->stackframesize & 1)
3826 cd->stackframesize++;
3828 /* create method header */
3830 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3831 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3832 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3833 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3834 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3835 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3836 (void) dseg_addlinenumbertablesize(cd);
3837 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3839 /* generate stub code */
3841 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3842 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3844 #if !defined(NDEBUG)
3845 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3846 emit_verbosecall_enter(jd);
3849 /* get function address (this must happen before the stackframeinfo) */
3851 funcdisp = dseg_add_functionptr(cd, f);
3853 #if !defined(WITH_STATIC_CLASSPATH)
3855 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3858 /* save integer and float argument registers */
3860 #if SIZEOF_VOID_P == 8
3861 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3862 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3863 M_AST(rd->argintregs[i], REG_SP, j * 8);
3868 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3869 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3870 if (!md->params[i].inmemory) {
3871 s1 = md->params[i].regoff;
3872 if (IS_2_WORD_TYPE(md->params[i].type)) {
3873 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3874 rd->argintregs[GET_HIGH_REG(s1)]);
3875 M_LST(s1, REG_SP, j * 8);
3878 M_IST(rd->argintregs[s1], REG_SP, j * 8);
3886 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3887 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3888 if (IS_2_WORD_TYPE(md->params[i].type))
3889 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3891 M_FST(rd->argfltregs[i], REG_SP, j * 8);
3896 /* prepare data structures for native function call */
3898 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3899 M_MOV(REG_PV, REG_A1);
3900 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3901 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3902 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3903 M_ALD(REG_ITMP3, REG_PV, disp);
3904 M_JSR(REG_RA, REG_ITMP3);
3905 M_NOP; /* XXX fill me! */
3907 /* restore integer and float argument registers */
3909 #if SIZEOF_VOID_P == 8
3910 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3911 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3912 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3917 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3918 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3919 if (!md->params[i].inmemory) {
3920 s1 = md->params[i].regoff;
3921 if (IS_2_WORD_TYPE(md->params[i].type)) {
3922 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3923 rd->argintregs[GET_HIGH_REG(s1)]);
3924 M_LLD(s1, REG_SP, j * 8);
3927 M_ILD(rd->argintregs[s1], REG_SP, j * 8);
3935 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3936 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3937 if (IS_2_WORD_TYPE(md->params[i].type))
3938 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
3940 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
3945 /* copy or spill arguments to new locations */
3947 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3948 t = md->params[i].type;
3950 if (IS_INT_LNG_TYPE(t)) {
3951 if (!md->params[i].inmemory) {
3952 s1 = md->params[i].regoff;
3953 #if SIZEOF_VOID_P == 8
3954 s1 = rd->argintregs[s1];
3956 if (IS_2_WORD_TYPE(t))
3957 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3958 rd->argintregs[GET_HIGH_REG(s1)]);
3960 s1 = rd->argintregs[s1];
3963 if (!nmd->params[j].inmemory) {
3964 s2 = nmd->params[j].regoff;
3965 #if SIZEOF_VOID_P == 8
3966 s2 = rd->argintregs[s2];
3969 if (IS_2_WORD_TYPE(t)) {
3970 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
3971 rd->argintregs[GET_HIGH_REG(s2)]);
3975 s2 = rd->argintregs[s2];
3981 s2 = nmd->params[j].regoff;
3983 #if SIZEOF_VOID_P == 8
3984 M_LST(s1, REG_SP, s2 * 8);
3986 if (IS_2_WORD_TYPE(t))
3987 M_LST(s1, REG_SP, s2 * 4);
3989 M_IST(s1, REG_SP, s2 * 4);
3994 s1 = md->params[i].regoff + cd->stackframesize;
3995 s2 = nmd->params[j].regoff;
3997 #if SIZEOF_VOID_P == 8
3998 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
3999 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4001 if (IS_2_WORD_TYPE(t)) {
4002 M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8);
4003 M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4);
4006 M_ILD(REG_ITMP1, REG_SP, s1 * 8);
4007 M_IST(REG_ITMP1, REG_SP, s2 * 4);
4013 if (!md->params[i].inmemory) {
4014 s1 = md->params[i].regoff;
4015 s2 = nmd->params[j].regoff;
4017 if (!nmd->params[j].inmemory) {
4018 #if SIZEOF_VOID_P == 8
4019 s1 = rd->argfltregs[s1];
4020 s2 = rd->argfltregs[s2];
4021 if (IS_2_WORD_TYPE(t))
4026 /* On MIPS32 float arguments for native functions
4027 can never be in float argument registers, since
4028 the first argument is _always_ an integer
4029 argument (JNIenv) */
4031 if (IS_2_WORD_TYPE(t)) {
4032 s1 = rd->argfltregs[s1];
4033 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
4034 rd->argintregs[GET_HIGH_REG(s2)]);
4036 /* double high/low order is endian
4037 independent: even numbered holds low
4038 32-bits, odd numbered high 32-bits */
4040 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
4041 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
4044 s1 = rd->argfltregs[s1];
4045 s2 = rd->argintregs[s2];
4051 #if SIZEOF_VOID_P == 8
4052 s1 = rd->argfltregs[s1];
4054 if (IS_2_WORD_TYPE(t))
4055 M_DST(s1, REG_SP, s2 * 8);
4057 M_FST(s1, REG_SP, s2 * 8);
4059 /* s1 may have been originally in 2 int registers,
4060 but was moved out by the native function
4061 argument(s), just get low register */
4063 s1 = rd->argfltregs[GET_LOW_REG(s1)];
4065 if (IS_2_WORD_TYPE(t))
4066 M_DST(s1, REG_SP, s2 * 4);
4068 M_FST(s1, REG_SP, s2 * 4);
4073 s1 = md->params[i].regoff + cd->stackframesize;
4074 s2 = nmd->params[j].regoff;
4076 if (IS_2_WORD_TYPE(t)) {
4077 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4078 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4081 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4082 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4088 /* put class into second argument register */
4090 if (m->flags & ACC_STATIC) {
4091 disp = dseg_add_address(cd, m->class);
4092 M_ALD(REG_A1, REG_PV, disp);
4095 /* put env into first argument register */
4097 disp = dseg_add_address(cd, _Jv_env);
4098 M_ALD(REG_A0, REG_PV, disp);
4100 /* do the native function call */
4102 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4103 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4104 M_NOP; /* delay slot */
4106 /* save return value */
4108 if (md->returntype.type != TYPE_VOID) {
4109 #if SIZEOF_VOID_P == 8
4110 if (IS_INT_LNG_TYPE(md->returntype.type))
4111 M_LST(REG_RESULT, REG_SP, 0 * 8);
4113 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4115 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4116 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4117 if (IS_2_WORD_TYPE(md->returntype.type))
4118 M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4121 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4125 #if !defined(NDEBUG)
4126 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4127 emit_verbosecall_exit(jd);
4130 /* remove native stackframe info */
4132 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
4133 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4134 M_ALD(REG_ITMP3, REG_PV, disp);
4135 M_JSR(REG_RA, REG_ITMP3);
4136 M_NOP; /* XXX fill me! */
4137 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4139 /* restore return value */
4141 if (md->returntype.type != TYPE_VOID) {
4142 #if SIZEOF_VOID_P == 8
4143 if (IS_INT_LNG_TYPE(md->returntype.type))
4144 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4146 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4148 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4149 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4150 if (IS_2_WORD_TYPE(md->returntype.type))
4151 M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4154 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4158 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4160 /* check for exception */
4162 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4163 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4165 M_RET(REG_RA); /* return to caller */
4166 M_NOP; /* DELAY SLOT */
4168 /* handle exception */
4170 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4171 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4172 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4173 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4175 /* generate patcher stubs */
4177 emit_patcher_stubs(jd);
4181 return code->entrypoint;
4186 * These are local overrides for various environment variables in Emacs.
4187 * Please do not remove this and leave it at the end of the file, where
4188 * Emacs will automagically detect them.
4189 * ---------------------------------------------------------------------
4192 * indent-tabs-mode: t
4196 * vim:noexpandtab:sw=4:ts=4: