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 7243 2007-01-28 23:35:29Z twisti $
39 #include "vm/jit/mips/arch.h"
40 #include "vm/jit/mips/codegen.h"
42 #include "native/native.h"
44 #if defined(ENABLE_THREADS)
45 # include "threads/native/lock.h"
48 #include "vm/builtin.h"
50 #include "vm/exceptions.h"
51 #include "vm/options.h"
52 #include "vm/stringlocal.h"
55 #include "vm/jit/asmpart.h"
56 #include "vm/jit/codegen-common.h"
57 #include "vm/jit/dseg.h"
58 #include "vm/jit/emit-common.h"
59 #include "vm/jit/jit.h"
60 #include "vm/jit/md.h"
61 #include "vm/jit/patcher.h"
62 #include "vm/jit/reg.h"
63 #include "vm/jit/replace.h"
65 #if defined(ENABLE_LSRA)
66 # include "vm/jit/allocator/lsra.h"
70 /* codegen *********************************************************************
72 Generates machine code.
74 *******************************************************************************/
76 bool codegen(jitdata *jd)
82 s4 len, s1, s2, s3, d, disp;
88 constant_classref *cr;
90 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
91 unresolved_method *um;
92 builtintable_entry *bte;
99 /* get required compiler data */
106 /* prevent compiler warnings */
121 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
123 /* space to save used callee saved registers */
125 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
126 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
128 cd->stackframesize = rd->memuse + savedregs_num;
130 #if defined(ENABLE_THREADS)
131 /* space to save argument of monitor_enter */
133 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
134 # if SIZEOF_VOID_P == 8
135 cd->stackframesize++;
138 cd->stackframesize += 2;
143 /* keep stack 16-byte aligned */
145 if (cd->stackframesize & 1)
146 cd->stackframesize++;
148 /* create method header */
150 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
151 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
153 #if defined(ENABLE_THREADS)
154 /* IsSync contains the offset relative to the stack pointer for the
155 argument of monitor_exit used in the exception handler. Since the
156 offset could be zero and give a wrong meaning of the flag it is
160 if (checksync && (m->flags & ACC_SYNCHRONIZED))
161 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
164 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
166 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
167 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
168 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
169 dseg_addlinenumbertablesize(cd);
170 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
172 /* create exception table */
174 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
175 dseg_add_target(cd, ex->start);
176 dseg_add_target(cd, ex->end);
177 dseg_add_target(cd, ex->handler);
178 (void) dseg_add_unique_address(cd, ex->catchtype.any);
181 /* create stack frame (if necessary) */
183 if (cd->stackframesize)
184 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
186 /* save return address and used callee saved registers */
188 p = cd->stackframesize;
189 if (!jd->isleafmethod) {
190 p--; M_AST(REG_RA, REG_SP, p * 8);
192 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
193 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
195 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
196 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
199 /* take arguments out of register or stack frame */
203 for (p = 0, l = 0; p < md->paramcount; p++) {
204 t = md->paramtypes[p].type;
206 varindex = jd->local_map[l * 5 + t];
209 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
212 if (varindex == UNUSED)
217 s1 = md->params[p].regoff;
218 if (IS_INT_LNG_TYPE(t)) { /* integer args */
219 if (!md->params[p].inmemory) { /* register arguments */
220 #if SIZEOF_VOID_P == 8
221 s2 = rd->argintregs[s1];
222 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
223 M_INTMOVE(s2, var->vv.regoff);
224 } else { /* reg arg -> spilled */
225 M_LST(s2, REG_SP, var->vv.regoff * 8);
228 if (IS_2_WORD_TYPE(t)) {
229 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
230 rd->argintregs[GET_HIGH_REG(s1)]);
231 if (!(var->flags & INMEMORY)) /* reg arg -> register */
232 M_LNGMOVE(s2, var->vv.regoff);
233 else /* reg arg -> spilled */
234 M_LST(s2, REG_SP, var->vv.regoff * 8);
237 s2 = rd->argintregs[s1];
238 if (!(var->flags & INMEMORY)) /* reg arg -> register */
239 M_INTMOVE(s2, var->vv.regoff);
240 else /* reg arg -> spilled */
241 M_IST(s2, REG_SP, var->vv.regoff * 8);
244 } else { /* stack arguments */
245 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
246 #if SIZEOF_VOID_P == 8
247 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
249 if (IS_2_WORD_TYPE(t))
250 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
252 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
254 } else { /* stack arg -> spilled */
255 var->vv.regoff = cd->stackframesize + s1;
259 } else { /* floating args */
260 if (!md->params[p].inmemory) { /* register arguments */
261 #if SIZEOF_VOID_P == 8
262 s2 = rd->argfltregs[s1];
263 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
264 if (IS_2_WORD_TYPE(t))
265 M_DMOV(s2, var->vv.regoff);
267 M_FMOV(s2, var->vv.regoff);
268 } else { /* reg arg -> spilled */
269 if (IS_2_WORD_TYPE(t))
270 M_DST(s2, REG_SP, var->vv.regoff * 8);
272 M_FST(s2, REG_SP, var->vv.regoff * 8);
276 ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
277 s2 = rd->argfltregs[s1];
278 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
279 if (IS_2_WORD_TYPE(t))
280 M_DBLMOVE(s2, var->vv.regoff);
282 M_FLTMOVE(s2, var->vv.regoff);
284 else { /* reg arg -> spilled */
285 if (IS_2_WORD_TYPE(t))
286 M_DST(s2, REG_SP, var->vv.regoff * 8);
288 M_FST(s2, REG_SP, var->vv.regoff * 8);
292 if (IS_2_WORD_TYPE(t)) {
293 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
294 rd->argintregs[GET_HIGH_REG(s1)]);
295 if (!(var->flags & INMEMORY)) {
296 M_MTC1(GET_LOW_REG(s2), var->vv.regoff);
297 M_MTC1(GET_HIGH_REG(s2), var->vv.regoff + 1);
301 M_LST(s2, REG_SP, var->vv.regoff * 8);
304 s2 = rd->argintregs[s1];
305 if (!(var->flags & INMEMORY)) {
306 M_MTC1(s2, var->vv.regoff);
310 M_IST(s2, REG_SP, var->vv.regoff * 8);
315 } else { /* stack arguments */
316 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
317 if (IS_2_WORD_TYPE(t))
318 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
320 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
321 } else /* stack-arg -> spilled */
322 var->vv.regoff = cd->stackframesize + s1;
327 /* call monitorenter function */
329 #if defined(ENABLE_THREADS)
330 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
331 /* stack offset for monitor argument */
335 # if !defined(NDEBUG)
336 if (opt_verbosecall) {
337 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
339 for (p = 0; p < INT_ARG_CNT; p++)
340 M_AST(rd->argintregs[p], REG_SP, p * 8);
342 for (p = 0; p < FLT_ARG_CNT; p++)
343 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
345 s1 += INT_ARG_CNT + FLT_ARG_CNT;
349 /* get correct lock object */
351 if (m->flags & ACC_STATIC) {
352 disp = dseg_add_address(cd, &m->class->object.header);
353 M_ALD(REG_A0, REG_PV, disp);
356 /* emit_nullpointer_check(cd, iptr, REG_A0); */
361 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
362 codegen_add_nullpointerexception_ref(cd);
363 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
368 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
369 M_ALD(REG_ITMP3, REG_PV, disp);
370 M_JSR(REG_RA, REG_ITMP3);
371 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
373 # if !defined(NDEBUG)
374 if (opt_verbosecall) {
375 for (p = 0; p < INT_ARG_CNT; p++)
376 M_ALD(rd->argintregs[p], REG_SP, p * 8);
378 for (p = 0; p < FLT_ARG_CNT; p++)
379 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
382 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
390 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
391 emit_verbosecall_enter(jd);
394 /* end of header generation */
396 /* create replacement points */
398 REPLACEMENT_POINTS_INIT(cd, jd);
400 /* walk through all basic blocks */
402 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
404 /* handle replacement points */
406 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
408 /* store relative start of block */
410 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
412 if (bptr->flags >= BBREACHED) {
413 /* branch resolving */
415 codegen_resolve_branchrefs(cd, bptr);
417 /* copy interface registers to their destination */
421 #if defined(ENABLE_LSRA)
425 src = bptr->invars[len];
426 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
427 /* d = reg_of_var(m, src, REG_ITMP1); */
428 if (!(src->flags & INMEMORY))
432 M_INTMOVE(REG_ITMP1, d);
433 emit_store(jd, NULL, src, d);
440 var = VAR(bptr->invars[len]);
441 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
442 d = codegen_reg_of_var(0, var, REG_ITMP1);
443 M_INTMOVE(REG_ITMP1, d);
444 emit_store(jd, NULL, var, d);
447 assert((var->flags & INOUT));
450 #if defined(ENABLE_LSRA)
453 /* walk through all instructions */
456 /* currentline = 0; */
458 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
459 if (iptr->line != currentline) {
460 dseg_addlinenumber(cd, iptr->line);
461 currentline = iptr->line;
464 MCODECHECK(64); /* an instruction usually needs < 64 words */
468 case ICMD_NOP: /* ... ==> ... */
469 case ICMD_POP: /* ..., value ==> ... */
470 case ICMD_POP2: /* ..., value, value ==> ... */
473 case ICMD_INLINE_START:
475 REPLACEMENT_POINT_INLINE_START(cd, iptr);
478 case ICMD_INLINE_BODY:
480 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
481 dseg_addlinenumber_inline_start(cd, iptr);
482 dseg_addlinenumber(cd, iptr->line);
485 case ICMD_INLINE_END:
487 dseg_addlinenumber_inline_end(cd, iptr);
488 dseg_addlinenumber(cd, iptr->line);
491 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
493 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
494 emit_nullpointer_check(cd, iptr, s1);
497 /* constant operations ************************************************/
499 case ICMD_ICONST: /* ... ==> ..., constant */
501 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
502 ICONST(d, iptr->sx.val.i);
503 emit_store_dst(jd, iptr, d);
506 case ICMD_LCONST: /* ... ==> ..., constant */
508 #if SIZEOF_VOID_P == 8
509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
511 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
513 LCONST(d, iptr->sx.val.l);
514 emit_store_dst(jd, iptr, d);
517 case ICMD_FCONST: /* ... ==> ..., constant */
519 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
520 disp = dseg_add_float(cd, iptr->sx.val.f);
521 M_FLD(d, REG_PV, disp);
522 emit_store_dst(jd, iptr, d);
525 case ICMD_DCONST: /* ... ==> ..., constant */
527 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
528 disp = dseg_add_double(cd, iptr->sx.val.d);
529 M_DLD(d, REG_PV, disp);
530 emit_store_dst(jd, iptr, d);
533 case ICMD_ACONST: /* ... ==> ..., constant */
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
537 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
538 cr = iptr->sx.val.c.ref;
539 disp = dseg_add_unique_address(cd, cr);
541 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
543 M_ALD(d, REG_PV, disp);
546 if (iptr->sx.val.anyptr == NULL)
547 M_INTMOVE(REG_ZERO, d);
549 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
550 M_ALD(d, REG_PV, disp);
553 emit_store_dst(jd, iptr, d);
557 /* load/store/copy/move operations ************************************/
559 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
560 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
561 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
562 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
563 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
564 case ICMD_ISTORE: /* ..., value ==> ... */
565 case ICMD_LSTORE: /* ..., value ==> ... */
566 case ICMD_FSTORE: /* ..., value ==> ... */
567 case ICMD_DSTORE: /* ..., value ==> ... */
571 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
575 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
576 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
580 /* integer operations *************************************************/
582 case ICMD_INEG: /* ..., value ==> ..., - value */
584 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
585 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
586 M_ISUB(REG_ZERO, s1, d);
587 emit_store_dst(jd, iptr, d);
590 case ICMD_LNEG: /* ..., value ==> ..., - value */
592 #if SIZEOF_VOID_P == 8
593 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
595 M_LSUB(REG_ZERO, s1, d);
597 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
598 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
599 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
600 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
601 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
602 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
604 emit_store_dst(jd, iptr, d);
607 case ICMD_I2L: /* ..., value ==> ..., value */
609 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
610 #if SIZEOF_VOID_P == 8
611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
614 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
615 M_INTMOVE(s1, GET_LOW_REG(d));
616 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
618 emit_store_dst(jd, iptr, d);
621 case ICMD_L2I: /* ..., value ==> ..., value */
623 #if SIZEOF_VOID_P == 8
624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
625 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
626 M_ISLL_IMM(s1, 0, d);
628 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
629 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
630 M_INTMOVE(GET_LOW_REG(s1), d);
632 emit_store_dst(jd, iptr, d);
635 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
637 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
639 #if SIZEOF_VOID_P == 8
640 M_LSLL_IMM(s1, 56, d);
641 M_LSRA_IMM( d, 56, d);
643 M_ISLL_IMM(s1, 24, d);
644 M_ISRA_IMM( d, 24, d);
646 emit_store_dst(jd, iptr, d);
649 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
653 M_AND_IMM(s1, 0xffff, d);
654 emit_store_dst(jd, iptr, d);
657 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 #if SIZEOF_VOID_P == 8
662 M_LSLL_IMM(s1, 48, d);
663 M_LSRA_IMM( d, 48, d);
665 M_ISLL_IMM(s1, 16, d);
666 M_ISRA_IMM( d, 16, d);
668 emit_store_dst(jd, iptr, d);
672 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
674 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
675 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
676 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
678 emit_store_dst(jd, iptr, d);
682 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
683 /* sx.val.i = constant */
685 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
686 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
687 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
688 M_IADD_IMM(s1, iptr->sx.val.i, d);
690 ICONST(REG_ITMP2, iptr->sx.val.i);
691 M_IADD(s1, REG_ITMP2, d);
693 emit_store_dst(jd, iptr, d);
696 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
698 #if SIZEOF_VOID_P == 8
699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
704 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
705 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
706 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
707 M_IADD(s1, s2, GET_HIGH_REG(d));
708 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
709 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
710 if (s1 == GET_LOW_REG(d)) {
711 M_MOV(s1, REG_ITMP3);
714 M_IADD(s1, s2, GET_LOW_REG(d));
715 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
716 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
718 emit_store_dst(jd, iptr, d);
721 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
722 /* sx.val.l = constant */
724 #if SIZEOF_VOID_P == 8
725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
727 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
728 M_LADD_IMM(s1, iptr->sx.val.l, d);
730 LCONST(REG_ITMP2, iptr->sx.val.l);
731 M_LADD(s1, REG_ITMP2, d);
734 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
735 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
736 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
737 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
738 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
739 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
741 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
742 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
743 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
744 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
745 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
746 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
747 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
750 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
751 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
752 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
753 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
754 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
755 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
756 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
757 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
760 emit_store_dst(jd, iptr, d);
763 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
765 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
766 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
767 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
769 emit_store_dst(jd, iptr, d);
772 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
773 /* sx.val.i = constant */
775 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
776 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
777 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
778 M_IADD_IMM(s1, -iptr->sx.val.i, d);
780 ICONST(REG_ITMP2, iptr->sx.val.i);
781 M_ISUB(s1, REG_ITMP2, d);
783 emit_store_dst(jd, iptr, d);
786 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
788 #if SIZEOF_VOID_P == 8
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
791 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
794 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
795 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
797 M_ISUB(s1, s2, GET_HIGH_REG(d));
798 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
799 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
800 M_CMPULT(s1, s2, REG_ITMP3);
801 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
802 /* if s1 is equal to REG_ITMP3 we have to reload it, since
803 the CMPULT instruction destroyed it */
805 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
806 M_ISUB(s1, s2, GET_LOW_REG(d));
809 emit_store_dst(jd, iptr, d);
812 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
813 /* sx.val.l = constant */
815 #if SIZEOF_VOID_P == 8
816 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
817 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
818 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
819 M_LADD_IMM(s1, -iptr->sx.val.l, d);
821 LCONST(REG_ITMP2, iptr->sx.val.l);
822 M_LSUB(s1, REG_ITMP2, d);
825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
826 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
827 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
828 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
829 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
830 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
831 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
832 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
834 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
835 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
836 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
837 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
838 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
841 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
842 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
843 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
844 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
845 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
846 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
847 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
848 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
851 emit_store_dst(jd, iptr, d);
854 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
856 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
857 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
858 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
863 emit_store_dst(jd, iptr, d);
866 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
867 /* sx.val.i = constant */
869 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
870 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 ICONST(REG_ITMP2, iptr->sx.val.i);
872 M_IMUL(s1, REG_ITMP2);
876 emit_store_dst(jd, iptr, d);
879 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
881 #if SIZEOF_VOID_P == 8
882 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
883 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
884 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
890 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
891 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
897 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
899 M_MFHI(GET_HIGH_REG(d));
900 M_MFLO(GET_LOW_REG(d));
903 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
905 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
906 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
909 /* XXX do we need nops here? */
911 emit_store_dst(jd, iptr, d);
914 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
915 /* sx.val.l = constant */
917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
918 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
919 LCONST(REG_ITMP2, iptr->sx.val.l);
920 M_LMUL(s1, REG_ITMP2);
924 emit_store_dst(jd, iptr, d);
927 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
929 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
930 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
931 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
932 emit_arithmetic_check(cd, iptr, s2);
937 emit_store_dst(jd, iptr, d);
940 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
942 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
943 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
944 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
945 emit_arithmetic_check(cd, iptr, s2);
950 emit_store_dst(jd, iptr, d);
953 #if SIZEOF_VOID_P == 8
955 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
958 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
959 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
960 emit_arithmetic_check(cd, iptr, s2);
965 emit_store_dst(jd, iptr, d);
968 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
970 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
971 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
972 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
973 emit_arithmetic_check(cd, iptr, s2);
978 emit_store_dst(jd, iptr, d);
981 #else /* SIZEOF_VOID_P == 8 */
983 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
984 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
986 bte = iptr->sx.s23.s3.bte;
989 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
990 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
991 emit_arithmetic_check(cd, iptr, REG_ITMP3);
993 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
994 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
997 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
998 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
999 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
1002 disp = dseg_add_functionptr(cd, bte->fp);
1003 M_ALD(REG_ITMP3, REG_PV, disp);
1004 M_JSR(REG_RA, REG_ITMP3);
1007 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1008 M_LNGMOVE(REG_RESULT_PACKED, d);
1009 emit_store_dst(jd, iptr, d);
1012 #endif /* SIZEOF_VOID_P == 8 */
1014 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1015 /* val.i = constant */
1017 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1018 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1019 #if SIZEOF_VOID_P == 8
1020 M_LSRA_IMM(s1, 63, REG_ITMP2);
1021 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1022 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1023 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1025 M_ISRA_IMM(s1, 31, REG_ITMP2);
1026 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
1027 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1028 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1030 emit_store_dst(jd, iptr, d);
1033 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1034 /* val.i = constant */
1036 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1037 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1039 M_MOV(s1, REG_ITMP1);
1042 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1043 M_AND_IMM(s1, iptr->sx.val.i, d);
1046 M_ISUB(REG_ZERO, s1, d);
1047 M_AND_IMM(d, iptr->sx.val.i, d);
1050 ICONST(REG_ITMP2, iptr->sx.val.i);
1051 M_AND(s1, REG_ITMP2, d);
1054 M_ISUB(REG_ZERO, s1, d);
1055 M_AND(d, REG_ITMP2, d);
1057 M_ISUB(REG_ZERO, d, d);
1058 emit_store_dst(jd, iptr, d);
1061 #if SIZEOF_VOID_P == 8
1063 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1064 /* val.i = constant */
1066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1068 M_LSRA_IMM(s1, 63, REG_ITMP2);
1069 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1070 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1071 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1072 emit_store_dst(jd, iptr, d);
1075 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1076 /* val.l = constant */
1078 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1079 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1081 M_MOV(s1, REG_ITMP1);
1084 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1085 M_AND_IMM(s1, iptr->sx.val.l, d);
1088 M_LSUB(REG_ZERO, s1, d);
1089 M_AND_IMM(d, iptr->sx.val.l, d);
1092 LCONST(REG_ITMP2, iptr->sx.val.l);
1093 M_AND(s1, REG_ITMP2, d);
1096 M_LSUB(REG_ZERO, s1, d);
1097 M_AND(d, REG_ITMP2, d);
1099 M_LSUB(REG_ZERO, d, d);
1100 emit_store_dst(jd, iptr, d);
1103 #endif /* SIZEOF_VOID_P == 8 */
1105 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1107 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1108 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1109 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1111 emit_store_dst(jd, iptr, d);
1114 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1115 /* sx.val.i = constant */
1117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1118 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1119 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1120 emit_store_dst(jd, iptr, d);
1123 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1126 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1127 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1129 emit_store_dst(jd, iptr, d);
1132 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1133 /* sx.val.i = constant */
1135 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1136 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1137 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1138 emit_store_dst(jd, iptr, d);
1141 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1144 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1145 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1147 emit_store_dst(jd, iptr, d);
1150 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1151 /* sx.val.i = constant */
1153 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1154 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1155 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1156 emit_store_dst(jd, iptr, d);
1159 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1161 #if SIZEOF_VOID_P == 8
1162 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1163 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1164 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1167 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1168 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1169 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1171 M_ISLL(s2, 26, REG_ITMP1);
1172 M_BGEZ(REG_ITMP1, 3);
1175 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1177 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1180 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1182 M_BEQZ(REG_ITMP1, 4);
1183 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1185 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1186 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1187 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1190 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1193 emit_store_dst(jd, iptr, d);
1196 #if SIZEOF_VOID_P == 8
1198 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1199 /* sx.val.i = constant */
1201 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1202 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1203 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1204 emit_store_dst(jd, iptr, d);
1207 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1210 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1211 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1213 emit_store_dst(jd, iptr, d);
1216 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1217 /* sx.val.i = constant */
1219 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1220 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1221 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1222 emit_store_dst(jd, iptr, d);
1225 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1227 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1228 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1229 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1231 emit_store_dst(jd, iptr, d);
1234 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1235 /* sx.val.i = constant */
1237 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1238 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1239 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1240 emit_store_dst(jd, iptr, d);
1243 #endif /* SIZEOF_VOID_P == 8 */
1245 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1247 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1248 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1249 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1251 emit_store_dst(jd, iptr, d);
1254 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1255 /* sx.val.i = constant */
1257 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1258 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1259 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1260 M_AND_IMM(s1, iptr->sx.val.i, d);
1262 ICONST(REG_ITMP2, iptr->sx.val.i);
1263 M_AND(s1, REG_ITMP2, d);
1265 emit_store_dst(jd, iptr, d);
1268 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1270 #if SIZEOF_VOID_P == 8
1271 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1272 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1273 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1276 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1277 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1278 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1279 M_AND(s1, s2, GET_LOW_REG(d));
1280 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1281 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1282 M_AND(s1, s2, GET_HIGH_REG(d));
1284 emit_store_dst(jd, iptr, d);
1287 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1288 /* sx.val.l = constant */
1290 #if SIZEOF_VOID_P == 8
1291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1293 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1294 M_AND_IMM(s1, iptr->sx.val.l, d);
1296 LCONST(REG_ITMP2, iptr->sx.val.l);
1297 M_AND(s1, REG_ITMP2, d);
1300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1301 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1302 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1303 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1304 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1307 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1308 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1309 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1310 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1311 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1314 emit_store_dst(jd, iptr, d);
1317 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1319 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1320 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1321 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1323 emit_store_dst(jd, iptr, d);
1326 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1327 /* sx.val.i = constant */
1329 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1330 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1331 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1332 M_OR_IMM(s1, iptr->sx.val.i, d);
1334 ICONST(REG_ITMP2, iptr->sx.val.i);
1335 M_OR(s1, REG_ITMP2, d);
1337 emit_store_dst(jd, iptr, d);
1340 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1342 #if SIZEOF_VOID_P == 8
1343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1344 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1345 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1348 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1349 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1350 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1351 M_OR(s1, s2, GET_LOW_REG(d));
1352 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1353 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1354 M_OR(s1, s2, GET_HIGH_REG(d));
1356 emit_store_dst(jd, iptr, d);
1359 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1360 /* sx.val.l = constant */
1362 #if SIZEOF_VOID_P == 8
1363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1364 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1365 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1366 M_OR_IMM(s1, iptr->sx.val.l, d);
1368 LCONST(REG_ITMP2, iptr->sx.val.l);
1369 M_OR(s1, REG_ITMP2, d);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1373 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1374 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1375 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1376 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1379 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1380 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1381 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1382 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1383 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1386 emit_store_dst(jd, iptr, d);
1389 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1391 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1392 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1393 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1395 emit_store_dst(jd, iptr, d);
1398 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1399 /* sx.val.i = constant */
1401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1402 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1403 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1404 M_XOR_IMM(s1, iptr->sx.val.i, d);
1406 ICONST(REG_ITMP2, iptr->sx.val.i);
1407 M_XOR(s1, REG_ITMP2, d);
1409 emit_store_dst(jd, iptr, d);
1412 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1414 #if SIZEOF_VOID_P == 8
1415 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1416 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1417 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1420 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1421 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1422 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1423 M_XOR(s1, s2, GET_LOW_REG(d));
1424 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1425 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1426 M_XOR(s1, s2, GET_HIGH_REG(d));
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1432 /* sx.val.l = constant */
1434 #if SIZEOF_VOID_P == 8
1435 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1436 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1437 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1438 M_XOR_IMM(s1, iptr->sx.val.l, d);
1440 LCONST(REG_ITMP2, iptr->sx.val.l);
1441 M_XOR(s1, REG_ITMP2, d);
1444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1445 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1446 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1447 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1448 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1451 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1452 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1453 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1454 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1455 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1458 emit_store_dst(jd, iptr, d);
1462 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1464 #if SIZEOF_VOID_P == 8
1465 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1466 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1467 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1468 M_CMPLT(s1, s2, REG_ITMP3);
1469 M_CMPLT(s2, s1, REG_ITMP1);
1470 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1472 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1473 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1474 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1475 M_CMPLT(s1, s2, REG_ITMP3);
1476 M_CMPLT(s2, s1, REG_ITMP1);
1477 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1480 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1481 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1482 M_CMPULT(s1, s2, REG_ITMP3);
1483 M_CMPULT(s2, s1, REG_ITMP1);
1484 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1486 emit_store_dst(jd, iptr, d);
1490 /* floating operations ************************************************/
1492 case ICMD_FNEG: /* ..., value ==> ..., - value */
1494 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1495 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1497 emit_store_dst(jd, iptr, d);
1500 case ICMD_DNEG: /* ..., value ==> ..., - value */
1502 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1503 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1505 emit_store_dst(jd, iptr, d);
1508 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1510 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1511 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1512 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1514 emit_store_dst(jd, iptr, d);
1517 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1519 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1520 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1521 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1523 emit_store_dst(jd, iptr, d);
1526 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1528 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1529 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1530 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1532 emit_store_dst(jd, iptr, d);
1535 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1537 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1538 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1539 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1541 emit_store_dst(jd, iptr, d);
1544 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1546 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1547 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1548 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1550 emit_store_dst(jd, iptr, d);
1553 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1555 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1556 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1557 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1559 emit_store_dst(jd, iptr, d);
1562 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1564 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1565 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1566 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1568 emit_store_dst(jd, iptr, d);
1571 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1573 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1574 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1575 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1577 emit_store_dst(jd, iptr, d);
1581 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1583 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1584 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1585 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1586 M_FDIV(s1,s2, REG_FTMP3);
1587 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1588 M_CVTLF(REG_FTMP3, REG_FTMP3);
1589 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1590 M_FSUB(s1, REG_FTMP3, d);
1591 emit_store_dst(jd, iptr, d);
1594 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1596 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1597 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1598 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1599 M_DDIV(s1,s2, REG_FTMP3);
1600 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1601 M_CVTLD(REG_FTMP3, REG_FTMP3);
1602 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1603 M_DSUB(s1, REG_FTMP3, d);
1604 emit_store_dst(jd, iptr, d);
1608 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1611 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1614 emit_store_dst(jd, iptr, d);
1617 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1619 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1620 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1623 emit_store_dst(jd, iptr, d);
1627 /* XXX these do not work correctly */
1629 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1631 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1633 M_TRUNCFI(s1, REG_FTMP1);
1634 M_MOVDI(REG_FTMP1, d);
1636 emit_store_dst(jd, iptr, d);
1639 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1641 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1643 M_TRUNCDI(s1, REG_FTMP1);
1644 M_MOVDI(REG_FTMP1, d);
1646 emit_store_dst(jd, iptr, d);
1649 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1651 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1653 M_TRUNCFL(s1, REG_FTMP1);
1654 M_MOVDL(REG_FTMP1, d);
1656 emit_store_dst(jd, iptr, d);
1659 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1661 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1663 M_TRUNCDL(s1, REG_FTMP1);
1664 M_MOVDL(REG_FTMP1, d);
1666 emit_store_dst(jd, iptr, d);
1670 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1672 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1673 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1675 emit_store_dst(jd, iptr, d);
1678 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1680 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1681 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1683 emit_store_dst(jd, iptr, d);
1686 #if SUPPORT_FLOAT_CMP
1687 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1689 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1690 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1694 M_AADD_IMM(REG_ZERO, 1, d);
1698 M_ASUB_IMM(REG_ZERO, 1, d);
1699 M_CMOVT(REG_ZERO, d);
1700 emit_store_dst(jd, iptr, d);
1703 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1705 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1706 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1710 M_ASUB_IMM(REG_ZERO, 1, d);
1714 M_AADD_IMM(REG_ZERO, 1, d);
1715 M_CMOVT(REG_ZERO, d);
1716 emit_store_dst(jd, iptr, d);
1720 #if SUPPORT_DOUBLE_CMP
1721 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1723 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1724 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1725 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1728 M_AADD_IMM(REG_ZERO, 1, d);
1732 M_ASUB_IMM(REG_ZERO, 1, d);
1733 M_CMOVT(REG_ZERO, d);
1734 emit_store_dst(jd, iptr, d);
1737 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1739 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1740 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1741 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1744 M_ASUB_IMM(REG_ZERO, 1, d);
1748 M_AADD_IMM(REG_ZERO, 1, d);
1749 M_CMOVT(REG_ZERO, d);
1750 emit_store_dst(jd, iptr, d);
1755 /* memory operations **************************************************/
1757 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1759 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1760 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1761 emit_nullpointer_check(cd, iptr, s1);
1762 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1763 emit_store_dst(jd, iptr, d);
1766 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1771 emit_array_checks(cd, iptr, s1, s2);
1772 M_AADD(s2, s1, REG_ITMP3);
1773 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1774 emit_store_dst(jd, iptr, d);
1777 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1779 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1780 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1781 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1782 emit_array_checks(cd, iptr, s1, s2);
1783 M_AADD(s2, s1, REG_ITMP3);
1784 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1785 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1786 emit_store_dst(jd, iptr, d);
1789 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1792 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1793 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1794 emit_array_checks(cd, iptr, s1, s2);
1795 M_AADD(s2, s1, REG_ITMP3);
1796 M_AADD(s2, REG_ITMP3, REG_ITMP3);
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_array_checks(cd, iptr, s1, s2);
1807 M_ASLL_IMM(s2, 2, REG_ITMP3);
1808 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1809 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1810 emit_store_dst(jd, iptr, d);
1813 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1815 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1816 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1817 #if SIZEOF_VOID_P == 8
1818 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1822 emit_array_checks(cd, iptr, s1, s2);
1823 M_ASLL_IMM(s2, 3, REG_ITMP3);
1824 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1825 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1826 emit_store_dst(jd, iptr, d);
1829 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1832 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1833 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1834 emit_array_checks(cd, iptr, s1, s2);
1835 M_ASLL_IMM(s2, 2, REG_ITMP3);
1836 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1837 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1838 emit_store_dst(jd, iptr, d);
1841 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1843 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1844 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1845 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1846 emit_array_checks(cd, iptr, s1, s2);
1847 M_ASLL_IMM(s2, 3, REG_ITMP3);
1848 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1849 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1850 emit_store_dst(jd, iptr, d);
1853 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1856 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1857 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1858 emit_array_checks(cd, iptr, s1, s2);
1859 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1860 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1861 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1862 emit_store_dst(jd, iptr, d);
1866 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1869 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1870 emit_array_checks(cd, iptr, s1, s2);
1871 M_AADD(s2, s1, REG_ITMP1);
1872 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1873 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1876 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1877 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1880 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1881 emit_array_checks(cd, iptr, s1, s2);
1882 M_AADD(s2, s1, REG_ITMP1);
1883 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1884 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1885 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1888 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1891 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1892 emit_array_checks(cd, iptr, s1, s2);
1893 M_ASLL_IMM(s2, 2, REG_ITMP2);
1894 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1895 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1896 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1899 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1901 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1902 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1903 emit_array_checks(cd, iptr, s1, s2);
1904 M_ASLL_IMM(s2, 3, REG_ITMP2);
1905 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1906 #if SIZEOF_VOID_P == 8
1907 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1909 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1911 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1914 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1916 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1917 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1918 emit_array_checks(cd, iptr, s1, s2);
1919 M_ASLL_IMM(s2, 2, REG_ITMP2);
1920 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1921 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1922 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1925 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1927 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1928 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1929 emit_array_checks(cd, iptr, s1, s2);
1930 M_ASLL_IMM(s2, 3, REG_ITMP2);
1931 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1932 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1933 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1937 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1939 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1940 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1941 emit_array_checks(cd, iptr, s1, s2);
1942 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1946 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1947 M_ALD(REG_ITMP3, REG_PV, disp);
1948 M_JSR(REG_RA, REG_ITMP3);
1951 /* M_BEQZ(REG_RESULT, 0); */
1952 /* codegen_add_arraystoreexception_ref(cd); */
1954 emit_arraystore_check(cd, iptr, REG_RESULT);
1956 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1957 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1958 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1959 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1960 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1961 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1965 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1968 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1969 emit_array_checks(cd, iptr, s1, s2);
1970 M_AADD(s2, s1, REG_ITMP1);
1971 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1974 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1975 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1977 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1978 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1979 emit_array_checks(cd, iptr, s1, s2);
1980 M_AADD(s2, s1, REG_ITMP1);
1981 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1982 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1985 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1987 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1988 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1989 emit_array_checks(cd, iptr, s1, s2);
1990 M_ASLL_IMM(s2, 2, REG_ITMP2);
1991 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1992 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1995 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1999 emit_array_checks(cd, iptr, s1, s2);
2000 M_ASLL_IMM(s2, 3, REG_ITMP2);
2001 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2002 #if SIZEOF_VOID_P == 8
2003 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2005 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
2009 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2011 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2012 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2013 emit_array_checks(cd, iptr, s1, s2);
2014 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
2015 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2016 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2020 case ICMD_GETSTATIC: /* ... ==> ..., value */
2022 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2023 uf = iptr->sx.s23.s3.uf;
2024 fieldtype = uf->fieldref->parseddesc.fd->type;
2025 disp = dseg_add_unique_address(cd, uf);
2027 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2030 fi = iptr->sx.s23.s3.fmiref->p.field;
2031 fieldtype = fi->type;
2032 disp = dseg_add_address(cd, &(fi->value));
2034 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2035 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2038 M_ALD(REG_ITMP1, REG_PV, disp);
2040 switch (fieldtype) {
2042 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2043 M_ILD_INTERN(d, REG_ITMP1, 0);
2046 #if SIZEOF_VOID_P == 8
2047 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2051 M_LLD_INTERN(d, REG_ITMP1, 0);
2054 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2055 M_ALD_INTERN(d, REG_ITMP1, 0);
2058 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2059 M_FLD_INTERN(d, REG_ITMP1, 0);
2062 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2063 M_DLD_INTERN(d, REG_ITMP1, 0);
2066 emit_store_dst(jd, iptr, d);
2069 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2071 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2072 uf = iptr->sx.s23.s3.uf;
2073 fieldtype = uf->fieldref->parseddesc.fd->type;
2074 disp = dseg_add_unique_address(cd, uf);
2076 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2079 fi = iptr->sx.s23.s3.fmiref->p.field;
2080 fieldtype = fi->type;
2081 disp = dseg_add_address(cd, &(fi->value));
2083 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2084 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2087 M_ALD(REG_ITMP1, REG_PV, disp);
2089 switch (fieldtype) {
2091 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2092 M_IST_INTERN(s1, REG_ITMP1, 0);
2095 #if SIZEOF_VOID_P == 8
2096 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2098 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2100 M_LST_INTERN(s1, REG_ITMP1, 0);
2103 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2104 M_AST_INTERN(s1, REG_ITMP1, 0);
2107 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2108 M_FST_INTERN(s1, REG_ITMP1, 0);
2111 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2112 M_DST_INTERN(s1, REG_ITMP1, 0);
2117 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2118 /* val = value (in current instruction) */
2119 /* following NOP) */
2121 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2122 uf = iptr->sx.s23.s3.uf;
2123 fieldtype = uf->fieldref->parseddesc.fd->type;
2124 disp = dseg_add_unique_address(cd, uf);
2126 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2129 fi = iptr->sx.s23.s3.fmiref->p.field;
2130 fieldtype = fi->type;
2131 disp = dseg_add_address(cd, &(fi->value));
2133 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2134 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2137 M_ALD(REG_ITMP1, REG_PV, disp);
2139 switch (fieldtype) {
2141 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2144 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2147 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2150 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2153 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2159 case ICMD_GETFIELD: /* ... ==> ..., value */
2161 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2162 emit_nullpointer_check(cd, iptr, s1);
2164 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2165 uf = iptr->sx.s23.s3.uf;
2166 fieldtype = uf->fieldref->parseddesc.fd->type;
2169 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2172 fi = iptr->sx.s23.s3.fmiref->p.field;
2173 fieldtype = fi->type;
2177 switch (fieldtype) {
2179 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2183 #if SIZEOF_VOID_P == 8
2184 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2187 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2188 M_LLD_GETFIELD(d, s1, disp);
2192 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2196 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2204 emit_store_dst(jd, iptr, d);
2207 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2210 emit_nullpointer_check(cd, iptr, s1);
2212 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2213 uf = iptr->sx.s23.s3.uf;
2214 fieldtype = uf->fieldref->parseddesc.fd->type;
2218 fi = iptr->sx.s23.s3.fmiref->p.field;
2219 fieldtype = fi->type;
2223 #if SIZEOF_VOID_P == 8
2224 if (IS_INT_LNG_TYPE(fieldtype))
2225 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2227 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2229 if (IS_INT_LNG_TYPE(fieldtype)) {
2230 if (IS_2_WORD_TYPE(fieldtype))
2231 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2233 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2236 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2239 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2240 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2242 switch (fieldtype) {
2244 M_IST(s2, s1, disp);
2247 M_LST(s2, s1, disp);
2250 M_AST(s2, s1, disp);
2253 M_FST(s2, s1, disp);
2256 M_DST(s2, s1, disp);
2261 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2263 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2264 emit_nullpointer_check(cd, iptr, s1);
2266 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2267 unresolved_field *uf = iptr->sx.s23.s3.uf;
2269 fieldtype = uf->fieldref->parseddesc.fd->type;
2272 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2275 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2276 fieldtype = fi->type;
2280 switch (fieldtype) {
2282 M_IST(REG_ZERO, s1, disp);
2285 M_LST(REG_ZERO, s1, disp);
2288 M_AST(REG_ZERO, s1, disp);
2291 M_FST(REG_ZERO, s1, disp);
2294 M_DST(REG_ZERO, s1, disp);
2300 /* branch operations **************************************************/
2302 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2304 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2305 M_INTMOVE(s1, REG_ITMP1_XPTR);
2307 #ifdef ENABLE_VERIFIER
2308 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2309 uc = iptr->sx.s23.s2.uc;
2311 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2313 #endif /* ENABLE_VERIFIER */
2315 disp = dseg_add_functionptr(cd, asm_handle_exception);
2316 M_ALD(REG_ITMP2, REG_PV, disp);
2317 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2319 M_NOP; /* nop ensures that XPC is less than the end */
2320 /* of basic block */
2324 case ICMD_GOTO: /* ... ==> ... */
2325 case ICMD_RET: /* ... ==> ... */
2328 codegen_add_branch_ref(cd, iptr->dst.block);
2333 case ICMD_JSR: /* ... ==> ... */
2336 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2341 case ICMD_IFNULL: /* ..., value ==> ... */
2343 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2345 codegen_add_branch_ref(cd, iptr->dst.block);
2349 case ICMD_IFNONNULL: /* ..., value ==> ... */
2351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2353 codegen_add_branch_ref(cd, iptr->dst.block);
2357 case ICMD_IFEQ: /* ..., value ==> ... */
2359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2360 if (iptr->sx.val.i == 0) {
2363 ICONST(REG_ITMP2, iptr->sx.val.i);
2364 M_BEQ(s1, REG_ITMP2, 0);
2366 codegen_add_branch_ref(cd, iptr->dst.block);
2370 case ICMD_IFLT: /* ..., value ==> ... */
2372 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2373 if (iptr->sx.val.i == 0) {
2376 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2377 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2379 ICONST(REG_ITMP2, iptr->sx.val.i);
2380 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2382 M_BNEZ(REG_ITMP1, 0);
2384 codegen_add_branch_ref(cd, iptr->dst.block);
2388 case ICMD_IFLE: /* ..., value ==> ... */
2390 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2391 if (iptr->sx.val.i == 0) {
2394 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2395 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2396 M_BNEZ(REG_ITMP1, 0);
2398 ICONST(REG_ITMP2, iptr->sx.val.i);
2399 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2400 M_BEQZ(REG_ITMP1, 0);
2403 codegen_add_branch_ref(cd, iptr->dst.block);
2407 case ICMD_IFNE: /* ..., value ==> ... */
2409 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2410 if (iptr->sx.val.i == 0) {
2413 ICONST(REG_ITMP2, iptr->sx.val.i);
2414 M_BNE(s1, REG_ITMP2, 0);
2416 codegen_add_branch_ref(cd, iptr->dst.block);
2420 case ICMD_IFGT: /* ..., value ==> ... */
2422 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2423 if (iptr->sx.val.i == 0) {
2426 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2427 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2428 M_BEQZ(REG_ITMP1, 0);
2430 ICONST(REG_ITMP2, iptr->sx.val.i);
2431 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2432 M_BNEZ(REG_ITMP1, 0);
2435 codegen_add_branch_ref(cd, iptr->dst.block);
2439 case ICMD_IFGE: /* ..., value ==> ... */
2441 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2442 if (iptr->sx.val.i == 0) {
2445 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2446 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2448 ICONST(REG_ITMP2, iptr->sx.val.i);
2449 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2451 M_BEQZ(REG_ITMP1, 0);
2453 codegen_add_branch_ref(cd, iptr->dst.block);
2457 case ICMD_IF_LEQ: /* ..., value ==> ... */
2459 #if SIZEOF_VOID_P == 8
2460 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2461 if (iptr->sx.val.l == 0) {
2464 LCONST(REG_ITMP2, iptr->sx.val.l);
2465 M_BEQ(s1, REG_ITMP2, 0);
2468 if (iptr->sx.val.l == 0) {
2469 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2470 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2471 M_BEQZ(REG_ITMP3, 0);
2474 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2475 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2476 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2477 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2478 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2479 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2480 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2481 M_BEQZ(REG_ITMP3, 0);
2484 codegen_add_branch_ref(cd, iptr->dst.block);
2488 case ICMD_IF_LLT: /* ..., value ==> ... */
2490 #if SIZEOF_VOID_P == 8
2491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2492 if (iptr->sx.val.l == 0) {
2495 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2496 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2498 LCONST(REG_ITMP2, iptr->sx.val.l);
2499 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2501 M_BNEZ(REG_ITMP1, 0);
2504 if (iptr->sx.val.l == 0) {
2505 /* if high word is less than zero, the whole long is too */
2506 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2510 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2511 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2512 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2513 M_BNEZ(REG_ITMP3, 0);
2514 codegen_add_branch_ref(cd, iptr->dst.block);
2516 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2517 M_BNE(s1, REG_ITMP2, 5);
2519 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2520 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2521 M_BNEZ(REG_ITMP3, 0);
2524 codegen_add_branch_ref(cd, iptr->dst.block);
2528 case ICMD_IF_LLE: /* ..., value ==> ... */
2530 #if SIZEOF_VOID_P == 8
2531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2532 if (iptr->sx.val.l == 0) {
2535 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2536 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2537 M_BNEZ(REG_ITMP1, 0);
2539 LCONST(REG_ITMP2, iptr->sx.val.l);
2540 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2541 M_BEQZ(REG_ITMP1, 0);
2545 if (iptr->sx.val.l == 0) {
2546 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2547 M_BGTZ(GET_HIGH_REG(s1), 5);
2549 M_BLTZ(GET_HIGH_REG(s1), 0);
2550 codegen_add_branch_ref(cd, iptr->dst.block);
2552 M_BEQZ(GET_LOW_REG(s1), 0);
2555 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2556 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2557 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2558 M_BNEZ(REG_ITMP3, 0);
2559 codegen_add_branch_ref(cd, iptr->dst.block);
2561 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2562 M_BNE(s1, REG_ITMP2, 5);
2564 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2565 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2566 M_BEQZ(REG_ITMP3, 0);
2569 codegen_add_branch_ref(cd, iptr->dst.block);
2573 case ICMD_IF_LNE: /* ..., value ==> ... */
2575 #if SIZEOF_VOID_P == 8
2576 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2577 if (iptr->sx.val.l == 0) {
2580 LCONST(REG_ITMP2, iptr->sx.val.l);
2581 M_BNE(s1, REG_ITMP2, 0);
2584 if (iptr->sx.val.l == 0) {
2585 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2586 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2587 M_BNEZ(REG_ITMP3, 0);
2590 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2591 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2592 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2593 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2594 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2595 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2596 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2597 M_BNEZ(REG_ITMP3, 0);
2600 codegen_add_branch_ref(cd, iptr->dst.block);
2604 case ICMD_IF_LGT: /* ..., value ==> ... */
2606 #if SIZEOF_VOID_P == 8
2607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2608 if (iptr->sx.val.l == 0) {
2611 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2612 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2613 M_BEQZ(REG_ITMP1, 0);
2615 LCONST(REG_ITMP2, iptr->sx.val.l);
2616 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2617 M_BNEZ(REG_ITMP1, 0);
2621 if (iptr->sx.val.l == 0) {
2622 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2623 M_BGTZ(GET_HIGH_REG(s1), 0);
2624 codegen_add_branch_ref(cd, iptr->dst.block);
2626 M_BLTZ(GET_HIGH_REG(s1), 3);
2628 M_BNEZ(GET_LOW_REG(s1), 0);
2631 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2632 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2633 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2634 M_BNEZ(REG_ITMP3, 0);
2635 codegen_add_branch_ref(cd, iptr->dst.block);
2637 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2638 M_BNE(s1, REG_ITMP2, 5);
2640 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2641 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2642 M_BNEZ(REG_ITMP3, 0);
2645 codegen_add_branch_ref(cd, iptr->dst.block);
2649 case ICMD_IF_LGE: /* ..., value ==> ... */
2651 #if SIZEOF_VOID_P == 8
2652 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2653 if (iptr->sx.val.l == 0) {
2656 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2657 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2659 LCONST(REG_ITMP2, iptr->sx.val.l);
2660 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2662 M_BEQZ(REG_ITMP1, 0);
2665 if (iptr->sx.val.l == 0) {
2666 /* if high word is greater equal zero, the whole long is too */
2667 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2671 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2672 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2673 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2674 M_BNEZ(REG_ITMP3, 0);
2675 codegen_add_branch_ref(cd, iptr->dst.block);
2677 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2678 M_BNE(s1, REG_ITMP2, 5);
2680 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2681 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2682 M_BEQZ(REG_ITMP3, 0);
2685 codegen_add_branch_ref(cd, iptr->dst.block);
2689 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2690 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2691 #if SIZEOF_VOID_P == 8
2692 case ICMD_IF_LCMPEQ:
2695 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2696 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2698 codegen_add_branch_ref(cd, iptr->dst.block);
2702 #if SIZEOF_VOID_P == 4
2703 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2704 /* op1 = target JavaVM pc */
2706 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2707 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2710 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2711 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2713 codegen_add_branch_ref(cd, iptr->dst.block);
2718 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2719 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2720 #if SIZEOF_VOID_P == 8
2721 case ICMD_IF_LCMPNE:
2724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2725 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2727 codegen_add_branch_ref(cd, iptr->dst.block);
2731 #if SIZEOF_VOID_P == 4
2732 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2734 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2735 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2737 codegen_add_branch_ref(cd, iptr->dst.block);
2739 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2740 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2742 codegen_add_branch_ref(cd, iptr->dst.block);
2747 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2748 #if SIZEOF_VOID_P == 8
2749 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2753 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2754 M_CMPLT(s1, s2, REG_ITMP3);
2755 M_BNEZ(REG_ITMP3, 0);
2756 codegen_add_branch_ref(cd, iptr->dst.block);
2760 #if SIZEOF_VOID_P == 4
2761 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2763 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2764 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2765 M_CMPLT(s1, s2, REG_ITMP3);
2766 M_BNEZ(REG_ITMP3, 0);
2767 codegen_add_branch_ref(cd, iptr->dst.block);
2769 M_CMPGT(s1, s2, REG_ITMP3);
2770 /* load low-bits before the branch, so we know the distance */
2771 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2772 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2773 M_BNEZ(REG_ITMP3, 4);
2775 M_CMPULT(s1, s2, REG_ITMP3);
2776 M_BNEZ(REG_ITMP3, 0);
2777 codegen_add_branch_ref(cd, iptr->dst.block);
2782 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2783 #if SIZEOF_VOID_P == 8
2784 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2788 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2789 M_CMPGT(s1, s2, REG_ITMP3);
2790 M_BNEZ(REG_ITMP3, 0);
2791 codegen_add_branch_ref(cd, iptr->dst.block);
2795 #if SIZEOF_VOID_P == 4
2796 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2798 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2799 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2800 M_CMPGT(s1, s2, REG_ITMP3);
2801 M_BNEZ(REG_ITMP3, 0);
2802 codegen_add_branch_ref(cd, iptr->dst.block);
2804 M_CMPLT(s1, s2, REG_ITMP3);
2805 /* load low-bits before the branch, so we know the distance */
2806 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2807 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2808 M_BNEZ(REG_ITMP3, 4);
2810 M_CMPUGT(s1, s2, REG_ITMP3);
2811 M_BNEZ(REG_ITMP3, 0);
2812 codegen_add_branch_ref(cd, iptr->dst.block);
2817 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2818 #if SIZEOF_VOID_P == 8
2819 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2823 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2824 M_CMPGT(s1, s2, REG_ITMP3);
2825 M_BEQZ(REG_ITMP3, 0);
2826 codegen_add_branch_ref(cd, iptr->dst.block);
2830 #if SIZEOF_VOID_P == 4
2831 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2833 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2834 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2835 M_CMPLT(s1, s2, REG_ITMP3);
2836 M_BNEZ(REG_ITMP3, 0);
2837 codegen_add_branch_ref(cd, iptr->dst.block);
2839 M_CMPGT(s1, s2, REG_ITMP3);
2840 /* load low-bits before the branch, so we know the distance */
2841 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2842 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2843 M_BNEZ(REG_ITMP3, 4);
2845 M_CMPUGT(s1, s2, REG_ITMP3);
2846 M_BEQZ(REG_ITMP3, 0);
2847 codegen_add_branch_ref(cd, iptr->dst.block);
2852 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2853 #if SIZEOF_VOID_P == 8
2854 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2857 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2858 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2859 M_CMPLT(s1, s2, REG_ITMP3);
2860 M_BEQZ(REG_ITMP3, 0);
2861 codegen_add_branch_ref(cd, iptr->dst.block);
2865 #if SIZEOF_VOID_P == 4
2866 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2868 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2869 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2870 M_CMPGT(s1, s2, REG_ITMP3);
2871 M_BNEZ(REG_ITMP3, 0);
2872 codegen_add_branch_ref(cd, iptr->dst.block);
2874 M_CMPLT(s1, s2, REG_ITMP3);
2875 /* load low-bits before the branch, so we know the distance */
2876 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2877 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2878 M_BNEZ(REG_ITMP3, 4);
2880 M_CMPULT(s1, s2, REG_ITMP3);
2881 M_BEQZ(REG_ITMP3, 0);
2882 codegen_add_branch_ref(cd, iptr->dst.block);
2887 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2888 #if SIZEOF_VOID_P == 8
2892 REPLACEMENT_POINT_RETURN(cd, iptr);
2893 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2894 M_INTMOVE(s1, REG_RESULT);
2895 goto nowperformreturn;
2897 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2899 REPLACEMENT_POINT_RETURN(cd, iptr);
2900 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2901 M_INTMOVE(s1, REG_RESULT);
2903 #ifdef ENABLE_VERIFIER
2904 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2905 uc = iptr->sx.s23.s2.uc;
2907 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2909 #endif /* ENABLE_VERIFIER */
2910 goto nowperformreturn;
2912 #if SIZEOF_VOID_P == 4
2913 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2915 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2916 M_LNGMOVE(s1, REG_RESULT_PACKED);
2917 goto nowperformreturn;
2920 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2921 REPLACEMENT_POINT_RETURN(cd, iptr);
2922 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2923 M_FLTMOVE(s1, REG_FRESULT);
2924 goto nowperformreturn;
2926 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2928 REPLACEMENT_POINT_RETURN(cd, iptr);
2929 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2930 M_DBLMOVE(s1, REG_FRESULT);
2931 goto nowperformreturn;
2933 case ICMD_RETURN: /* ... ==> ... */
2935 REPLACEMENT_POINT_RETURN(cd, iptr);
2941 p = cd->stackframesize;
2943 #if !defined(NDEBUG)
2944 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2945 emit_verbosecall_exit(jd);
2948 #if defined(ENABLE_THREADS)
2949 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2950 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2951 M_ALD(REG_ITMP3, REG_PV, disp);
2953 /* we need to save the proper return value */
2955 switch (iptr->opc) {
2958 #if SIZEOF_VOID_P == 8
2961 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2962 M_JSR(REG_RA, REG_ITMP3);
2963 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2965 #if SIZEOF_VOID_P == 4
2967 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2968 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2969 M_JSR(REG_RA, REG_ITMP3);
2975 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2976 M_JSR(REG_RA, REG_ITMP3);
2977 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2980 M_JSR(REG_RA, REG_ITMP3);
2981 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2985 /* and now restore the proper return value */
2987 switch (iptr->opc) {
2990 #if SIZEOF_VOID_P == 8
2993 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2995 #if SIZEOF_VOID_P == 4
2997 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
3002 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
3008 /* restore return address */
3010 if (!jd->isleafmethod) {
3011 p--; M_ALD(REG_RA, REG_SP, p * 8);
3014 /* restore saved registers */
3016 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3017 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
3019 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3020 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3023 /* deallocate stack and return */
3025 if (cd->stackframesize) {
3028 disp = cd->stackframesize * 8;
3029 lo = (short) (disp);
3030 hi = (short) (((disp) - lo) >> 16);
3034 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
3036 M_LUI(REG_ITMP3,hi);
3037 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
3039 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
3052 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3055 branch_target_t *table;
3057 table = iptr->dst.table;
3059 l = iptr->sx.s23.s2.tablelow;
3060 i = iptr->sx.s23.s3.tablehigh;
3062 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3064 {M_INTMOVE(s1, REG_ITMP1);}
3065 else if (l <= 32768) {
3066 M_IADD_IMM(s1, -l, REG_ITMP1);
3069 ICONST(REG_ITMP2, l);
3070 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3073 /* number of targets */
3078 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3079 M_BEQZ(REG_ITMP2, 0);
3080 codegen_add_branch_ref(cd, table[0].block); /* default target */
3081 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot */
3083 /* build jump table top down and use address of lowest entry */
3088 dseg_add_target(cd, table->block);
3093 /* length of dataseg after last dseg_add_target is used by load */
3095 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3096 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3103 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3106 lookup_target_t *lookup;
3108 lookup = iptr->dst.lookup;
3110 i = iptr->sx.s23.s2.lookupcount;
3112 MCODECHECK((i<<2)+8);
3113 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3116 ICONST(REG_ITMP2, lookup->value);
3117 M_BEQ(s1, REG_ITMP2, 0);
3118 codegen_add_branch_ref(cd, lookup->target.block);
3124 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
3131 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3133 bte = iptr->sx.s23.s3.bte;
3137 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3139 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3140 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3141 case ICMD_INVOKEINTERFACE:
3143 REPLACEMENT_POINT_INVOKE(cd, iptr);
3145 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3147 um = iptr->sx.s23.s3.um;
3148 md = um->methodref->parseddesc.md;
3151 lm = iptr->sx.s23.s3.fmiref->p.method;
3153 md = lm->parseddesc;
3157 s3 = md->paramcount;
3159 MCODECHECK((s3 << 1) + 64);
3161 /* copy arguments to registers or stack location */
3163 for (s3 = s3 - 1; s3 >= 0; s3--) {
3164 var = VAR(iptr->sx.s23.s2.args[s3]);
3166 if (var->flags & PREALLOC)
3169 if (IS_INT_LNG_TYPE(var->type)) {
3170 #if SIZEOF_VOID_P == 8
3171 if (!md->params[s3].inmemory) {
3172 s1 = rd->argintregs[md->params[s3].regoff];
3173 d = emit_load(jd, iptr, var, s1);
3177 d = emit_load(jd, iptr, var, REG_ITMP1);
3178 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3181 if (!md->params[s3].inmemory) {
3182 if (IS_2_WORD_TYPE(var->type)) {
3183 s1 = md->params[s3].regoff;
3184 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3185 rd->argintregs[GET_HIGH_REG(s1)]);
3186 d = emit_load(jd, iptr, var, s1);
3190 s1 = rd->argintregs[md->params[s3].regoff];
3191 d = emit_load(jd, iptr, var, s1);
3196 if (IS_2_WORD_TYPE(var->type)) {
3197 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3198 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3201 d = emit_load(jd, iptr, var, REG_ITMP1);
3202 M_IST(d, REG_SP, md->params[s3].regoff * 8);
3208 if (!md->params[s3].inmemory) {
3209 #if SIZEOF_VOID_P == 8
3210 s1 = rd->argfltregs[md->params[s3].regoff];
3211 d = emit_load(jd, iptr, var, s1);
3212 if (IS_2_WORD_TYPE(var->type))
3218 ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
3219 s1 = rd->argfltregs[md->params[s3].regoff];
3220 d = emit_load(jd, iptr, var, s1);
3221 if (IS_2_WORD_TYPE(var->type))
3227 if (IS_2_WORD_TYPE(var->type)) {
3228 s1 = md->params[s3].regoff;
3229 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3230 rd->argintregs[GET_HIGH_REG(s1)]);
3231 d = emit_load(jd, iptr, var, REG_FTMP1);
3232 M_MFC1(GET_LOW_REG(s2), d);
3233 M_MFC1(GET_HIGH_REG(s2), d + 1);
3237 s1 = rd->argintregs[md->params[s3].regoff];
3238 d = emit_load(jd, iptr, var, s1);
3246 d = emit_load(jd, iptr, var, REG_FTMP1);
3247 if (IS_2_WORD_TYPE(var->type))
3248 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3250 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3255 switch (iptr->opc) {
3257 disp = dseg_add_functionptr(cd, bte->fp);
3259 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3261 /* TWISTI: i actually don't know the reason for using
3262 REG_ITMP3 here instead of REG_PV. */
3266 case ICMD_INVOKESPECIAL:
3267 /* emit_nullpointer_check(cd, REG_A0); */
3271 M_LUI(REG_ITMP3, 0);
3272 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
3273 codegen_add_nullpointerexception_ref(cd);
3274 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
3280 case ICMD_INVOKESTATIC:
3282 disp = dseg_add_unique_address(cd, um);
3284 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
3288 disp = dseg_add_address(cd, lm->stubroutine);
3290 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3294 case ICMD_INVOKEVIRTUAL:
3295 emit_nullpointer_check(cd, iptr, REG_A0);
3298 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
3303 s1 = OFFSET(vftbl_t, table[0]) +
3304 sizeof(methodptr) * lm->vftblindex;
3306 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3307 M_ALD(REG_PV, REG_METHODPTR, s1);
3311 case ICMD_INVOKEINTERFACE:
3312 emit_nullpointer_check(cd, iptr, REG_A0);
3315 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
3321 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3322 sizeof(methodptr*) * lm->class->index;
3324 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3327 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3328 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3329 M_ALD(REG_PV, REG_METHODPTR, s2);
3334 /* generate the actual call */
3338 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3339 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3340 M_LDA(REG_PV, REG_RA, -disp);
3342 /* actually only used for ICMD_BUILTIN */
3344 emit_exception_check(cd, iptr);
3346 /* store return value */
3348 d = md->returntype.type;
3350 if (d != TYPE_VOID) {
3351 if (IS_INT_LNG_TYPE(d)) {
3352 #if SIZEOF_VOID_P == 8
3353 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3354 M_INTMOVE(REG_RESULT, s1);
3356 if (IS_2_WORD_TYPE(d)) {
3357 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3358 M_LNGMOVE(REG_RESULT_PACKED, s1);
3361 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3362 M_INTMOVE(REG_RESULT, s1);
3367 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3368 if (IS_2_WORD_TYPE(d))
3369 M_DMOV(REG_FRESULT, s1);
3371 M_FMOV(REG_FRESULT, s1);
3373 emit_store_dst(jd, iptr, s1);
3378 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3379 /* val.a: (classinfo*) superclass */
3381 /* superclass is an interface:
3383 * OK if ((sub == NULL) ||
3384 * (sub->vftbl->interfacetablelength > super->index) &&
3385 * (sub->vftbl->interfacetable[-super->index] != NULL));
3387 * superclass is a class:
3389 * OK if ((sub == NULL) || (0
3390 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3391 * super->vftbl->diffvall));
3394 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3398 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3403 super = iptr->sx.s23.s3.c.cls;
3404 superindex = super->index;
3407 #if defined(ENABLE_THREADS)
3408 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3411 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3413 /* calculate interface checkcast code size */
3415 /* s2 = 3 + 2 + 1 + 2; */
3418 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3420 /* calculate class checkcast code size */
3422 /* s3 = 2 + 1 + 4 + 1 + 2 /\* 10 + (s1 == REG_ITMP1) *\/; */
3423 s3 = 2 + 1 + 4 + 1 + 7;
3425 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3427 /* if class is not resolved, check which code to call */
3429 if (super == NULL) {
3430 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
3433 cr = iptr->sx.s23.s3.c.ref;
3434 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3436 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3439 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3440 M_ILD(REG_ITMP2, REG_PV, disp);
3441 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3442 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3446 /* interface checkcast code */
3448 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3449 if (super == NULL) {
3450 cr = iptr->sx.s23.s3.c.ref;
3452 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3460 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3461 M_ILD(REG_ITMP3, REG_ITMP2,
3462 OFFSET(vftbl_t, interfacetablelength));
3463 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3464 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3466 M_ALD(REG_ITMP3, REG_ITMP2,
3467 OFFSET(vftbl_t, interfacetable[0]) -
3468 superindex * sizeof(methodptr*));
3469 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3471 if (super == NULL) {
3477 /* class checkcast code */
3479 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3480 if (super == NULL) {
3481 cr = iptr->sx.s23.s3.c.ref;
3482 disp = dseg_add_unique_address(cd, NULL);
3484 codegen_add_patch_ref(cd,
3485 PATCHER_checkcast_instanceof_class,
3489 disp = dseg_add_address(cd, super->vftbl);
3495 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3496 M_ALD(REG_ITMP3, REG_PV, disp);
3497 #if defined(ENABLE_THREADS)
3498 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3500 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3501 /* if (s1 != REG_ITMP1) { */
3502 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3503 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3504 /* #if defined(ENABLE_THREADS) */
3505 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3507 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3509 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3510 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3511 M_ALD(REG_ITMP3, REG_PV, disp);
3512 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3513 #if defined(ENABLE_THREADS)
3514 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3517 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3518 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3521 d = codegen_reg_of_dst(jd, iptr, s1);
3524 s1 = emit_load_s1(jd, iptr, REG_A0);
3525 M_INTMOVE(s1, REG_A0);
3527 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3528 cr = iptr->sx.s23.s3.c.ref;
3529 disp = dseg_add_unique_address(cd, NULL);
3531 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3535 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3537 M_ALD(REG_A1, REG_PV, disp);
3538 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3539 M_ALD(REG_ITMP3, REG_PV, disp);
3540 M_JSR(REG_RA, REG_ITMP3);
3543 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3544 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3546 d = codegen_reg_of_dst(jd, iptr, s1);
3550 emit_store_dst(jd, iptr, d);
3553 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3554 /* val.a: (classinfo*) superclass */
3556 /* superclass is an interface:
3558 * return (sub != NULL) &&
3559 * (sub->vftbl->interfacetablelength > super->index) &&
3560 * (sub->vftbl->interfacetable[-super->index] != NULL);
3562 * superclass is a class:
3564 * return ((sub != NULL) && (0
3565 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3566 * super->vftbl->diffvall));
3573 super = iptr->sx.s23.s3.c.cls;
3575 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3580 super = iptr->sx.s23.s3.c.cls;
3581 superindex = super->index;
3584 #if defined(ENABLE_THREADS)
3585 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3591 M_MOV(s1, REG_ITMP1);
3595 /* calculate interface instanceof code size */
3599 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3601 /* calculate class instanceof code size */
3605 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3609 /* if class is not resolved, check which code to call */
3611 if (super == NULL) {
3612 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
3615 cr = iptr->sx.s23.s3.c.ref;
3616 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3618 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3621 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3622 M_ILD(REG_ITMP3, REG_PV, disp);
3623 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3624 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3628 /* interface instanceof code */
3630 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3631 if (super == NULL) {
3632 cr = iptr->sx.s23.s3.c.ref;
3634 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3642 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3643 M_ILD(REG_ITMP3, REG_ITMP1,
3644 OFFSET(vftbl_t, interfacetablelength));
3645 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3646 M_BLEZ(REG_ITMP3, 3);
3648 M_ALD(REG_ITMP1, REG_ITMP1,
3649 OFFSET(vftbl_t, interfacetable[0]) -
3650 superindex * sizeof(methodptr*));
3651 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3653 if (super == NULL) {
3659 /* class instanceof code */
3661 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3662 if (super == NULL) {
3663 cr = iptr->sx.s23.s3.c.ref;
3664 disp = dseg_add_unique_address(cd, NULL);
3666 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3670 disp = dseg_add_address(cd, super->vftbl);
3676 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3677 M_ALD(REG_ITMP2, REG_PV, disp);
3678 #if defined(ENABLE_THREADS)
3679 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3681 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3682 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3683 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3684 #if defined(ENABLE_THREADS)
3685 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3687 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3688 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3691 emit_store_dst(jd, iptr, d);
3695 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3697 /* check for negative sizes and copy sizes to stack if necessary */
3699 MCODECHECK((iptr->s1.argcount << 1) + 64);
3701 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3703 var = VAR(iptr->sx.s23.s2.args[s1]);
3705 /* copy SAVEDVAR sizes to stack */
3707 if (!(var->flags & PREALLOC)) {
3708 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3709 #if SIZEOF_VOID_P == 8
3710 M_LST(s2, REG_SP, s1 * 8);
3712 M_IST(s2, REG_SP, (s1 + 2) * 8);
3717 /* a0 = dimension count */
3719 ICONST(REG_A0, iptr->s1.argcount);
3721 /* is patcher function set? */
3723 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3724 cr = iptr->sx.s23.s3.c.ref;
3725 disp = dseg_add_unique_address(cd, NULL);
3727 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3731 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3733 /* a1 = arraydescriptor */
3735 M_ALD(REG_A1, REG_PV, disp);
3737 /* a2 = pointer to dimensions = stack pointer */
3739 #if SIZEOF_VOID_P == 8
3740 M_MOV(REG_SP, REG_A2);
3742 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3745 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3746 M_ALD(REG_ITMP3, REG_PV, disp);
3747 M_JSR(REG_RA, REG_ITMP3);
3750 /* check for exception before result assignment */
3752 emit_exception_check(cd, iptr);
3754 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3755 M_INTMOVE(REG_RESULT, d);
3756 emit_store_dst(jd, iptr, d);
3760 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3765 } /* for instruction */
3767 MCODECHECK(64); /* XXX require smaller number? */
3769 /* At the end of a basic block we may have to append some nops,
3770 because the patcher stub calling code might be longer than the
3771 actual instruction. So codepatching does not change the
3772 following block unintentionally. */
3774 if (cd->mcodeptr < cd->lastmcodeptr) {
3775 while (cd->mcodeptr < cd->lastmcodeptr)
3779 } /* if (bptr -> flags >= BBREACHED) */
3780 } /* for basic block */
3782 dseg_createlinenumbertable(cd);
3784 /* generate exception and patcher stubs */
3786 emit_exception_stubs(jd);
3787 emit_patcher_stubs(jd);
3788 REPLACEMENT_EMIT_STUBS(jd);
3792 /* everything's ok */
3798 /* createcompilerstub **********************************************************
3800 Creates a stub routine which calls the compiler.
3802 *******************************************************************************/
3804 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3805 #define COMPILERSTUB_CODESIZE 4 * 4
3807 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3810 u1 *createcompilerstub(methodinfo *m)
3812 u1 *s; /* memory to hold the stub */
3817 s = CNEW(u1, COMPILERSTUB_SIZE);
3819 /* set data pointer and code pointer */
3822 s = s + COMPILERSTUB_DATASIZE;
3824 /* mark start of dump memory area */
3826 dumpsize = dump_size();
3828 cd = DNEW(codegendata);
3831 /* The codeinfo pointer is actually a pointer to the
3832 methodinfo. This fakes a codeinfo structure. */
3834 d[0] = (ptrint) asm_call_jit_compiler;
3836 d[2] = (ptrint) &d[1]; /* fake code->m */
3838 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3839 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3843 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3845 #if defined(ENABLE_STATISTICS)
3847 count_cstub_len += COMPILERSTUB_SIZE;
3850 /* release dump area */
3852 dump_release(dumpsize);
3858 /* createnativestub ************************************************************
3860 Creates a stub routine which calls a native method.
3862 *******************************************************************************/
3864 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3872 s4 i, j; /* count variables */
3875 s4 funcdisp; /* displacement of the function */
3877 /* get required compiler data */
3884 /* initialize variables */
3887 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3889 /* calculate stack frame size */
3891 cd->stackframesize =
3892 1 + /* return address */
3893 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3894 sizeof(localref_table) / SIZEOF_VOID_P +
3895 md->paramcount + /* for saving arguments over calls */
3896 #if SIZEOF_VOID_P == 4
3897 5 + /* additional save space (MIPS32) */
3899 1 + /* for saving return address */
3902 /* adjust stackframe size for 16-byte alignment */
3904 if (cd->stackframesize & 1)
3905 cd->stackframesize++;
3907 /* create method header */
3909 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3910 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3911 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3912 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3913 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3914 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3915 (void) dseg_addlinenumbertablesize(cd);
3916 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3918 /* generate stub code */
3920 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3921 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3923 #if !defined(NDEBUG)
3924 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3925 emit_verbosecall_enter(jd);
3928 /* get function address (this must happen before the stackframeinfo) */
3930 funcdisp = dseg_add_functionptr(cd, f);
3932 #if !defined(WITH_STATIC_CLASSPATH)
3934 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3937 /* save integer and float argument registers */
3939 #if SIZEOF_VOID_P == 8
3940 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3941 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3942 M_AST(rd->argintregs[i], REG_SP, j * 8);
3947 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3948 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3949 if (!md->params[i].inmemory) {
3950 s1 = md->params[i].regoff;
3951 if (IS_2_WORD_TYPE(md->params[i].type)) {
3952 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3953 rd->argintregs[GET_HIGH_REG(s1)]);
3954 M_LST(s1, REG_SP, j * 8);
3957 M_IST(rd->argintregs[s1], REG_SP, j * 8);
3965 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3966 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3967 if (IS_2_WORD_TYPE(md->params[i].type))
3968 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3970 M_FST(rd->argfltregs[i], REG_SP, j * 8);
3975 /* prepare data structures for native function call */
3977 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3978 M_MOV(REG_PV, REG_A1);
3979 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3980 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3981 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3982 M_ALD(REG_ITMP3, REG_PV, disp);
3983 M_JSR(REG_RA, REG_ITMP3);
3984 M_NOP; /* XXX fill me! */
3986 /* restore integer and float argument registers */
3988 #if SIZEOF_VOID_P == 8
3989 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3990 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3991 M_LLD(rd->argintregs[i], REG_SP, j * 8);
3996 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3997 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3998 if (!md->params[i].inmemory) {
3999 s1 = md->params[i].regoff;
4000 if (IS_2_WORD_TYPE(md->params[i].type)) {
4001 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
4002 rd->argintregs[GET_HIGH_REG(s1)]);
4003 M_LLD(s1, REG_SP, j * 8);
4006 M_ILD(rd->argintregs[s1], REG_SP, j * 8);
4014 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4015 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
4016 if (IS_2_WORD_TYPE(md->params[i].type))
4017 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4019 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4024 /* copy or spill arguments to new locations */
4026 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4027 t = md->params[i].type;
4029 if (IS_INT_LNG_TYPE(t)) {
4030 if (!md->params[i].inmemory) {
4031 s1 = md->params[i].regoff;
4032 #if SIZEOF_VOID_P == 8
4033 s1 = rd->argintregs[s1];
4035 if (IS_2_WORD_TYPE(t))
4036 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
4037 rd->argintregs[GET_HIGH_REG(s1)]);
4039 s1 = rd->argintregs[s1];
4042 if (!nmd->params[j].inmemory) {
4043 s2 = nmd->params[j].regoff;
4044 #if SIZEOF_VOID_P == 8
4045 s2 = rd->argintregs[s2];
4048 if (IS_2_WORD_TYPE(t)) {
4049 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
4050 rd->argintregs[GET_HIGH_REG(s2)]);
4054 s2 = rd->argintregs[s2];
4060 s2 = nmd->params[j].regoff;
4062 #if SIZEOF_VOID_P == 8
4063 M_LST(s1, REG_SP, s2 * 8);
4065 if (IS_2_WORD_TYPE(t))
4066 M_LST(s1, REG_SP, s2 * 4);
4068 M_IST(s1, REG_SP, s2 * 4);
4073 s1 = md->params[i].regoff + cd->stackframesize;
4074 s2 = nmd->params[j].regoff;
4076 #if SIZEOF_VOID_P == 8
4077 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4078 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4080 if (IS_2_WORD_TYPE(t)) {
4081 M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8);
4082 M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4);
4085 M_ILD(REG_ITMP1, REG_SP, s1 * 8);
4086 M_IST(REG_ITMP1, REG_SP, s2 * 4);
4092 if (!md->params[i].inmemory) {
4093 s1 = md->params[i].regoff;
4094 s2 = nmd->params[j].regoff;
4096 if (!nmd->params[j].inmemory) {
4097 #if SIZEOF_VOID_P == 8
4098 s1 = rd->argfltregs[s1];
4099 s2 = rd->argfltregs[s2];
4100 if (IS_2_WORD_TYPE(t))
4105 /* On MIPS32 float arguments for native functions
4106 can never be in float argument registers, since
4107 the first argument is _always_ an integer
4108 argument (JNIenv) */
4110 if (IS_2_WORD_TYPE(t)) {
4111 s1 = rd->argfltregs[s1];
4112 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
4113 rd->argintregs[GET_HIGH_REG(s2)]);
4115 /* double high/low order is endian
4116 independent: even numbered holds low
4117 32-bits, odd numbered high 32-bits */
4119 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
4120 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
4123 s1 = rd->argfltregs[s1];
4124 s2 = rd->argintregs[s2];
4130 #if SIZEOF_VOID_P == 8
4131 s1 = rd->argfltregs[s1];
4133 if (IS_2_WORD_TYPE(t))
4134 M_DST(s1, REG_SP, s2 * 8);
4136 M_FST(s1, REG_SP, s2 * 8);
4138 /* s1 may have been originally in 2 int registers,
4139 but was moved out by the native function
4140 argument(s), just get low register */
4142 s1 = rd->argfltregs[GET_LOW_REG(s1)];
4144 if (IS_2_WORD_TYPE(t))
4145 M_DST(s1, REG_SP, s2 * 4);
4147 M_FST(s1, REG_SP, s2 * 4);
4152 s1 = md->params[i].regoff + cd->stackframesize;
4153 s2 = nmd->params[j].regoff;
4155 if (IS_2_WORD_TYPE(t)) {
4156 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4157 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4160 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4161 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4167 /* put class into second argument register */
4169 if (m->flags & ACC_STATIC) {
4170 disp = dseg_add_address(cd, m->class);
4171 M_ALD(REG_A1, REG_PV, disp);
4174 /* put env into first argument register */
4176 disp = dseg_add_address(cd, _Jv_env);
4177 M_ALD(REG_A0, REG_PV, disp);
4179 /* do the native function call */
4181 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4182 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4183 M_NOP; /* delay slot */
4185 /* save return value */
4187 if (md->returntype.type != TYPE_VOID) {
4188 #if SIZEOF_VOID_P == 8
4189 if (IS_INT_LNG_TYPE(md->returntype.type))
4190 M_LST(REG_RESULT, REG_SP, 0 * 8);
4192 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4194 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4195 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4196 if (IS_2_WORD_TYPE(md->returntype.type))
4197 M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4200 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4204 #if !defined(NDEBUG)
4205 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4206 emit_verbosecall_exit(jd);
4209 /* remove native stackframe info */
4211 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
4212 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4213 M_ALD(REG_ITMP3, REG_PV, disp);
4214 M_JSR(REG_RA, REG_ITMP3);
4215 M_NOP; /* XXX fill me! */
4216 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4218 /* restore return value */
4220 if (md->returntype.type != TYPE_VOID) {
4221 #if SIZEOF_VOID_P == 8
4222 if (IS_INT_LNG_TYPE(md->returntype.type))
4223 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4225 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4227 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4228 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4229 if (IS_2_WORD_TYPE(md->returntype.type))
4230 M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4233 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4237 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4239 /* check for exception */
4241 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4242 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4244 M_RET(REG_RA); /* return to caller */
4245 M_NOP; /* DELAY SLOT */
4247 /* handle exception */
4249 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4250 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4251 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4252 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4254 /* generate patcher stubs */
4256 emit_patcher_stubs(jd);
4260 return code->entrypoint;
4265 * These are local overrides for various environment variables in Emacs.
4266 * Please do not remove this and leave it at the end of the file, where
4267 * Emacs will automagically detect them.
4268 * ---------------------------------------------------------------------
4271 * indent-tabs-mode: t
4275 * vim:noexpandtab:sw=4:ts=4: