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
37 #include "vm/jit/mips/arch.h"
38 #include "vm/jit/mips/codegen.h"
40 #include "mm/memory.h"
42 #include "native/localref.h"
43 #include "native/native.h"
45 #include "threads/lock-common.h"
47 #include "vm/builtin.h"
48 #include "vm/exceptions.h"
51 #include "vm/jit/abi.h"
52 #include "vm/jit/asmpart.h"
53 #include "vm/jit/codegen-common.h"
54 #include "vm/jit/dseg.h"
55 #include "vm/jit/emit-common.h"
56 #include "vm/jit/jit.h"
57 #include "vm/jit/linenumbertable.h"
58 #include "vm/jit/md.h"
59 #include "vm/jit/patcher-common.h"
60 #include "vm/jit/reg.h"
61 #include "vm/jit/replace.h"
63 #if defined(ENABLE_LSRA)
64 # include "vm/jit/allocator/lsra.h"
67 #include "vmcore/class.h"
68 #include "vmcore/options.h"
71 /* codegen_emit ****************************************************************
73 Generates machine code.
75 *******************************************************************************/
77 bool codegen_emit(jitdata *jd)
83 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 = code_is_leafmethod(code) ? 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 && code_is_synchronized(code)) {
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 code->synchronizedoffset = rd->memuse * 8;
155 /* REMOVEME: We still need it for exception handling in assembler. */
157 if (code_is_leafmethod(code))
158 (void) dseg_add_unique_s4(cd, 1);
160 (void) dseg_add_unique_s4(cd, 0);
162 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
163 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
165 /* create stack frame (if necessary) */
167 if (cd->stackframesize)
168 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
170 /* save return address and used callee saved registers */
172 p = cd->stackframesize;
173 if (!code_is_leafmethod(code)) {
174 p--; M_AST(REG_RA, REG_SP, p * 8);
176 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
177 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
179 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
180 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
183 /* take arguments out of register or stack frame */
187 for (p = 0, l = 0; p < md->paramcount; p++) {
188 t = md->paramtypes[p].type;
190 varindex = jd->local_map[l * 5 + t];
193 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
196 if (varindex == UNUSED)
200 s1 = md->params[p].regoff;
202 if (IS_INT_LNG_TYPE(t)) { /* integer args */
203 if (!md->params[p].inmemory) { /* register arguments */
204 #if SIZEOF_VOID_P == 8
205 if (!(var->flags & INMEMORY))
206 M_INTMOVE(s1, var->vv.regoff);
208 M_LST(s1, REG_SP, var->vv.regoff);
210 if (!(var->flags & INMEMORY)) {
211 if (IS_2_WORD_TYPE(t))
212 M_LNGMOVE(s1, var->vv.regoff);
214 M_INTMOVE(s1, var->vv.regoff);
217 if (IS_2_WORD_TYPE(t))
218 M_LST(s1, REG_SP, var->vv.regoff);
220 M_IST(s1, REG_SP, var->vv.regoff);
224 else { /* stack arguments */
225 if (!(var->flags & INMEMORY)) {
226 #if SIZEOF_VOID_P == 8
227 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
229 if (IS_2_WORD_TYPE(t))
230 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
232 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
236 var->vv.regoff = cd->stackframesize * 8 + s1;
239 else { /* floating args */
240 if (!md->params[p].inmemory) {
241 if (!(var->flags & INMEMORY)) {
242 if (IS_2_WORD_TYPE(t))
243 M_DBLMOVE(s1, var->vv.regoff);
245 M_FLTMOVE(s1, var->vv.regoff);
248 if (IS_2_WORD_TYPE(t))
249 M_DST(s1, REG_SP, var->vv.regoff);
251 M_FST(s1, REG_SP, var->vv.regoff);
255 if (!(var->flags & INMEMORY)) {
256 if (IS_2_WORD_TYPE(t))
257 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
259 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
262 var->vv.regoff = cd->stackframesize * 8 + s1;
267 /* call monitorenter function */
269 #if defined(ENABLE_THREADS)
270 if (checksync && code_is_synchronized(code)) {
271 /* stack offset for monitor argument */
275 # if !defined(NDEBUG)
276 if (opt_verbosecall) {
277 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
279 for (p = 0; p < INT_ARG_CNT; p++)
280 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
282 for (p = 0; p < FLT_ARG_CNT; p++)
283 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
285 s1 += INT_ARG_CNT + FLT_ARG_CNT;
289 /* get correct lock object */
291 if (m->flags & ACC_STATIC) {
292 disp = dseg_add_address(cd, &m->class->object.header);
293 M_ALD(REG_A0, REG_PV, disp);
294 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
295 M_ALD(REG_ITMP3, REG_PV, disp);
298 /* emit_nullpointer_check(cd, iptr, REG_A0); */
300 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
301 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
302 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
305 M_JSR(REG_RA, REG_ITMP3);
306 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
308 # if !defined(NDEBUG)
309 if (opt_verbosecall) {
310 for (p = 0; p < INT_ARG_CNT; p++)
311 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
313 for (p = 0; p < FLT_ARG_CNT; p++)
314 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
317 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
325 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
326 emit_verbosecall_enter(jd);
329 /* end of header generation */
331 /* create replacement points */
333 REPLACEMENT_POINTS_INIT(cd, jd);
335 /* walk through all basic blocks */
337 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
339 /* handle replacement points */
341 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
343 /* store relative start of block */
345 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
347 if (bptr->flags >= BBREACHED) {
348 /* branch resolving */
350 codegen_resolve_branchrefs(cd, bptr);
352 /* copy interface registers to their destination */
356 #if defined(ENABLE_LSRA)
360 src = bptr->invars[len];
361 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
362 /* d = reg_of_var(m, src, REG_ITMP1); */
363 if (!(src->flags & INMEMORY))
367 M_INTMOVE(REG_ITMP1, d);
368 emit_store(jd, NULL, src, d);
375 var = VAR(bptr->invars[len]);
376 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
377 d = codegen_reg_of_var(0, var, REG_ITMP1);
378 M_INTMOVE(REG_ITMP1, d);
379 emit_store(jd, NULL, var, d);
382 assert((var->flags & INOUT));
385 #if defined(ENABLE_LSRA)
388 /* walk through all instructions */
391 /* currentline = 0; */
393 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
394 if (iptr->line != currentline) {
395 linenumbertable_list_entry_add(cd, iptr->line);
396 currentline = iptr->line;
399 MCODECHECK(64); /* an instruction usually needs < 64 words */
403 case ICMD_NOP: /* ... ==> ... */
404 case ICMD_POP: /* ..., value ==> ... */
405 case ICMD_POP2: /* ..., value, value ==> ... */
408 case ICMD_INLINE_START:
410 REPLACEMENT_POINT_INLINE_START(cd, iptr);
413 case ICMD_INLINE_BODY:
415 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
416 linenumbertable_list_entry_add_inline_start(cd, iptr);
417 linenumbertable_list_entry_add(cd, iptr->line);
420 case ICMD_INLINE_END:
422 linenumbertable_list_entry_add_inline_end(cd, iptr);
423 linenumbertable_list_entry_add(cd, iptr->line);
426 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
428 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
429 emit_nullpointer_check(cd, iptr, s1);
432 /* constant operations ************************************************/
434 case ICMD_ICONST: /* ... ==> ..., constant */
436 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
437 ICONST(d, iptr->sx.val.i);
438 emit_store_dst(jd, iptr, d);
441 case ICMD_LCONST: /* ... ==> ..., constant */
443 #if SIZEOF_VOID_P == 8
444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
446 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
448 LCONST(d, iptr->sx.val.l);
449 emit_store_dst(jd, iptr, d);
452 case ICMD_FCONST: /* ... ==> ..., constant */
454 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
455 disp = dseg_add_float(cd, iptr->sx.val.f);
456 M_FLD(d, REG_PV, disp);
457 emit_store_dst(jd, iptr, d);
460 case ICMD_DCONST: /* ... ==> ..., constant */
462 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
463 disp = dseg_add_double(cd, iptr->sx.val.d);
464 M_DLD(d, REG_PV, disp);
465 emit_store_dst(jd, iptr, d);
468 case ICMD_ACONST: /* ... ==> ..., constant */
470 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
472 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
473 cr = iptr->sx.val.c.ref;
474 disp = dseg_add_unique_address(cd, cr);
476 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
479 M_ALD(d, REG_PV, disp);
482 if (iptr->sx.val.anyptr == NULL)
483 M_INTMOVE(REG_ZERO, d);
485 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
486 M_ALD(d, REG_PV, disp);
489 emit_store_dst(jd, iptr, d);
493 /* load/store/copy/move operations ************************************/
495 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
500 case ICMD_ISTORE: /* ..., value ==> ... */
511 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
516 /* integer operations *************************************************/
518 case ICMD_INEG: /* ..., value ==> ..., - value */
520 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
522 M_ISUB(REG_ZERO, s1, d);
523 emit_store_dst(jd, iptr, d);
526 case ICMD_LNEG: /* ..., value ==> ..., - value */
528 #if SIZEOF_VOID_P == 8
529 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
531 M_LSUB(REG_ZERO, s1, d);
533 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
534 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
535 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
536 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
537 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
538 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
540 emit_store_dst(jd, iptr, d);
543 case ICMD_I2L: /* ..., value ==> ..., value */
545 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
546 #if SIZEOF_VOID_P == 8
547 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
550 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
551 M_INTMOVE(s1, GET_LOW_REG(d));
552 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
554 emit_store_dst(jd, iptr, d);
557 case ICMD_L2I: /* ..., value ==> ..., value */
559 #if SIZEOF_VOID_P == 8
560 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
561 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
562 M_ISLL_IMM(s1, 0, d);
564 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
565 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
566 M_INTMOVE(GET_LOW_REG(s1), d);
568 emit_store_dst(jd, iptr, d);
571 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
575 #if SIZEOF_VOID_P == 8
576 M_LSLL_IMM(s1, 56, d);
577 M_LSRA_IMM( d, 56, d);
579 M_ISLL_IMM(s1, 24, d);
580 M_ISRA_IMM( d, 24, d);
582 emit_store_dst(jd, iptr, d);
585 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
587 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
588 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
589 M_AND_IMM(s1, 0xffff, d);
590 emit_store_dst(jd, iptr, d);
593 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
596 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
597 #if SIZEOF_VOID_P == 8
598 M_LSLL_IMM(s1, 48, d);
599 M_LSRA_IMM( d, 48, d);
601 M_ISLL_IMM(s1, 16, d);
602 M_ISRA_IMM( d, 16, d);
604 emit_store_dst(jd, iptr, d);
608 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
611 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
612 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
614 emit_store_dst(jd, iptr, d);
618 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
619 /* sx.val.i = constant */
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
623 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
624 M_IADD_IMM(s1, iptr->sx.val.i, d);
626 ICONST(REG_ITMP2, iptr->sx.val.i);
627 M_IADD(s1, REG_ITMP2, d);
629 emit_store_dst(jd, iptr, d);
632 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
634 #if SIZEOF_VOID_P == 8
635 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
636 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
640 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
641 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
643 M_IADD(s1, s2, GET_HIGH_REG(d));
644 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
645 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
646 if (s1 == GET_LOW_REG(d)) {
647 M_MOV(s1, REG_ITMP3);
650 M_IADD(s1, s2, GET_LOW_REG(d));
651 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
652 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
654 emit_store_dst(jd, iptr, d);
657 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
658 /* sx.val.l = constant */
660 #if SIZEOF_VOID_P == 8
661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
663 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
664 M_LADD_IMM(s1, iptr->sx.val.l, d);
666 LCONST(REG_ITMP2, iptr->sx.val.l);
667 M_LADD(s1, REG_ITMP2, d);
670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
671 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
672 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
673 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
674 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
675 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
677 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
678 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
679 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
680 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
681 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
682 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
683 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
686 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
687 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
688 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
689 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
690 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
691 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
692 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
693 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
696 emit_store_dst(jd, iptr, d);
699 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
702 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
703 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
705 emit_store_dst(jd, iptr, d);
708 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
709 /* sx.val.i = constant */
711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
712 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
713 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
714 M_IADD_IMM(s1, -iptr->sx.val.i, d);
716 ICONST(REG_ITMP2, iptr->sx.val.i);
717 M_ISUB(s1, REG_ITMP2, d);
719 emit_store_dst(jd, iptr, d);
722 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
724 #if SIZEOF_VOID_P == 8
725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
726 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
727 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
730 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
731 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
732 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
733 M_ISUB(s1, s2, GET_HIGH_REG(d));
734 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
735 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
736 M_CMPULT(s1, s2, REG_ITMP3);
737 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
738 /* if s1 is equal to REG_ITMP3 we have to reload it, since
739 the CMPULT instruction destroyed it */
741 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
742 M_ISUB(s1, s2, GET_LOW_REG(d));
745 emit_store_dst(jd, iptr, d);
748 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
749 /* sx.val.l = constant */
751 #if SIZEOF_VOID_P == 8
752 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
754 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
755 M_LADD_IMM(s1, -iptr->sx.val.l, d);
757 LCONST(REG_ITMP2, iptr->sx.val.l);
758 M_LSUB(s1, REG_ITMP2, d);
761 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
762 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
763 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
764 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
765 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
766 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
767 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
768 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
770 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
771 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
772 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
773 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
774 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
777 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
778 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
779 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
780 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
781 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
782 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
783 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
784 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
787 emit_store_dst(jd, iptr, d);
790 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
792 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
793 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
799 emit_store_dst(jd, iptr, d);
802 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
803 /* sx.val.i = constant */
805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
807 ICONST(REG_ITMP2, iptr->sx.val.i);
808 M_IMUL(s1, REG_ITMP2);
812 emit_store_dst(jd, iptr, d);
815 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
817 #if SIZEOF_VOID_P == 8
818 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
819 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
820 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
826 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
827 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
828 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
833 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
835 M_MFHI(GET_HIGH_REG(d));
836 M_MFLO(GET_LOW_REG(d));
839 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
841 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
842 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
845 /* XXX do we need nops here? */
847 emit_store_dst(jd, iptr, d);
850 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
851 /* sx.val.l = constant */
853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
854 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
855 LCONST(REG_ITMP2, iptr->sx.val.l);
856 M_LMUL(s1, REG_ITMP2);
860 emit_store_dst(jd, iptr, d);
863 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
865 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
866 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
867 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
868 emit_arithmetic_check(cd, iptr, s2);
873 emit_store_dst(jd, iptr, d);
876 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
878 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
879 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
880 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
881 emit_arithmetic_check(cd, iptr, s2);
886 emit_store_dst(jd, iptr, d);
889 #if SIZEOF_VOID_P == 8
891 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
893 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
894 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
895 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
896 emit_arithmetic_check(cd, iptr, s2);
901 emit_store_dst(jd, iptr, d);
904 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
906 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
907 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
908 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
909 emit_arithmetic_check(cd, iptr, s2);
914 emit_store_dst(jd, iptr, d);
917 #else /* SIZEOF_VOID_P == 8 */
919 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
920 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
922 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
923 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
925 /* XXX TODO: only do this if arithmetic check is really done! */
926 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
927 emit_arithmetic_check(cd, iptr, REG_ITMP3);
929 M_LNGMOVE(s1, REG_A0_A1_PACKED);
930 M_LNGMOVE(s2, REG_A2_A3_PACKED);
932 bte = iptr->sx.s23.s3.bte;
933 disp = dseg_add_functionptr(cd, bte->fp);
934 M_ALD(REG_ITMP3, REG_PV, disp);
935 M_JSR(REG_RA, REG_ITMP3);
938 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
939 M_LNGMOVE(REG_RESULT_PACKED, d);
940 emit_store_dst(jd, iptr, d);
943 #endif /* SIZEOF_VOID_P == 8 */
945 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
946 /* val.i = constant */
948 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
949 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
950 #if SIZEOF_VOID_P == 8
951 M_LSRA_IMM(s1, 63, REG_ITMP2);
952 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
953 M_LADD(s1, REG_ITMP2, REG_ITMP2);
954 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
956 M_ISRA_IMM(s1, 31, REG_ITMP2);
957 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
958 M_IADD(s1, REG_ITMP2, REG_ITMP2);
959 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
961 emit_store_dst(jd, iptr, d);
964 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
965 /* val.i = constant */
967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
968 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
970 M_MOV(s1, REG_ITMP1);
973 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
974 M_AND_IMM(s1, iptr->sx.val.i, d);
977 M_ISUB(REG_ZERO, s1, d);
978 M_AND_IMM(d, iptr->sx.val.i, d);
981 ICONST(REG_ITMP2, iptr->sx.val.i);
982 M_AND(s1, REG_ITMP2, d);
985 M_ISUB(REG_ZERO, s1, d);
986 M_AND(d, REG_ITMP2, d);
988 M_ISUB(REG_ZERO, d, d);
989 emit_store_dst(jd, iptr, d);
992 #if SIZEOF_VOID_P == 8
994 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
995 /* val.i = constant */
997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
998 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
999 M_LSRA_IMM(s1, 63, REG_ITMP2);
1000 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1001 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1002 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1003 emit_store_dst(jd, iptr, d);
1006 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1007 /* val.l = constant */
1009 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1010 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1012 M_MOV(s1, REG_ITMP1);
1015 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1016 M_AND_IMM(s1, iptr->sx.val.l, d);
1019 M_LSUB(REG_ZERO, s1, d);
1020 M_AND_IMM(d, iptr->sx.val.l, d);
1023 LCONST(REG_ITMP2, iptr->sx.val.l);
1024 M_AND(s1, REG_ITMP2, d);
1027 M_LSUB(REG_ZERO, s1, d);
1028 M_AND(d, REG_ITMP2, d);
1030 M_LSUB(REG_ZERO, d, d);
1031 emit_store_dst(jd, iptr, d);
1034 #endif /* SIZEOF_VOID_P == 8 */
1036 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1038 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1039 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1040 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1042 emit_store_dst(jd, iptr, d);
1045 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1046 /* sx.val.i = constant */
1048 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1049 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1050 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1051 emit_store_dst(jd, iptr, d);
1054 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1056 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1057 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1058 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1060 emit_store_dst(jd, iptr, d);
1063 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1064 /* sx.val.i = constant */
1066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1067 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1068 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1069 emit_store_dst(jd, iptr, d);
1072 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1076 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1078 emit_store_dst(jd, iptr, d);
1081 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1082 /* sx.val.i = constant */
1084 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1085 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1086 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1087 emit_store_dst(jd, iptr, d);
1090 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1092 #if SIZEOF_VOID_P == 8
1093 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1094 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1095 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1098 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1099 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1100 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1102 M_ISLL(s2, 26, REG_ITMP1);
1103 M_BGEZ(REG_ITMP1, 3);
1106 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1108 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1111 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1113 M_BEQZ(REG_ITMP1, 4);
1114 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1116 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1117 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1118 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1121 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1124 emit_store_dst(jd, iptr, d);
1127 #if SIZEOF_VOID_P == 8
1129 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1130 /* sx.val.i = constant */
1132 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1134 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1135 emit_store_dst(jd, iptr, d);
1138 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1140 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1141 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1142 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1144 emit_store_dst(jd, iptr, d);
1147 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1148 /* sx.val.i = constant */
1150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1152 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1153 emit_store_dst(jd, iptr, d);
1156 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1159 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1160 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1162 emit_store_dst(jd, iptr, d);
1165 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1166 /* sx.val.i = constant */
1168 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1169 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1170 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1171 emit_store_dst(jd, iptr, d);
1174 #endif /* SIZEOF_VOID_P == 8 */
1176 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1178 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1179 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1180 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1182 emit_store_dst(jd, iptr, d);
1185 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1186 /* sx.val.i = constant */
1188 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1189 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1190 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1191 M_AND_IMM(s1, iptr->sx.val.i, d);
1193 ICONST(REG_ITMP2, iptr->sx.val.i);
1194 M_AND(s1, REG_ITMP2, d);
1196 emit_store_dst(jd, iptr, d);
1199 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1201 #if SIZEOF_VOID_P == 8
1202 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1203 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1204 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1207 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1208 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1209 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1210 M_AND(s1, s2, GET_LOW_REG(d));
1211 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1212 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1213 M_AND(s1, s2, GET_HIGH_REG(d));
1215 emit_store_dst(jd, iptr, d);
1218 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1219 /* sx.val.l = constant */
1221 #if SIZEOF_VOID_P == 8
1222 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1223 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1224 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1225 M_AND_IMM(s1, iptr->sx.val.l, d);
1227 LCONST(REG_ITMP2, iptr->sx.val.l);
1228 M_AND(s1, REG_ITMP2, d);
1231 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1232 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1233 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1234 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1235 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1238 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1239 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1240 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1241 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1242 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1245 emit_store_dst(jd, iptr, d);
1248 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1250 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1251 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1252 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1254 emit_store_dst(jd, iptr, d);
1257 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1258 /* sx.val.i = constant */
1260 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1261 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1262 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1263 M_OR_IMM(s1, iptr->sx.val.i, d);
1265 ICONST(REG_ITMP2, iptr->sx.val.i);
1266 M_OR(s1, REG_ITMP2, d);
1268 emit_store_dst(jd, iptr, d);
1271 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1273 #if SIZEOF_VOID_P == 8
1274 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1275 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1276 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1279 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1280 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1281 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1282 M_OR(s1, s2, GET_LOW_REG(d));
1283 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1284 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1285 M_OR(s1, s2, GET_HIGH_REG(d));
1287 emit_store_dst(jd, iptr, d);
1290 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1291 /* sx.val.l = constant */
1293 #if SIZEOF_VOID_P == 8
1294 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1295 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1296 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1297 M_OR_IMM(s1, iptr->sx.val.l, d);
1299 LCONST(REG_ITMP2, iptr->sx.val.l);
1300 M_OR(s1, REG_ITMP2, d);
1303 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1304 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1305 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1306 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1307 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1310 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1311 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1312 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1313 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1314 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1317 emit_store_dst(jd, iptr, d);
1320 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1322 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1323 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1324 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1326 emit_store_dst(jd, iptr, d);
1329 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1330 /* sx.val.i = constant */
1332 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1333 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1334 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1335 M_XOR_IMM(s1, iptr->sx.val.i, d);
1337 ICONST(REG_ITMP2, iptr->sx.val.i);
1338 M_XOR(s1, REG_ITMP2, d);
1340 emit_store_dst(jd, iptr, d);
1343 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1345 #if SIZEOF_VOID_P == 8
1346 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1347 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1348 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1351 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1352 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1354 M_XOR(s1, s2, GET_LOW_REG(d));
1355 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1356 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1357 M_XOR(s1, s2, GET_HIGH_REG(d));
1359 emit_store_dst(jd, iptr, d);
1362 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1363 /* sx.val.l = constant */
1365 #if SIZEOF_VOID_P == 8
1366 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1367 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1368 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1369 M_XOR_IMM(s1, iptr->sx.val.l, d);
1371 LCONST(REG_ITMP2, iptr->sx.val.l);
1372 M_XOR(s1, REG_ITMP2, d);
1375 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1376 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1377 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1378 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1379 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1382 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1383 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1384 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1385 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1386 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1389 emit_store_dst(jd, iptr, d);
1393 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1395 #if SIZEOF_VOID_P == 8
1396 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1397 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1398 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1399 M_CMPLT(s1, s2, REG_ITMP3);
1400 M_CMPLT(s2, s1, REG_ITMP1);
1401 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1403 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1404 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1405 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1406 M_CMPLT(s1, s2, REG_ITMP3);
1407 M_CMPLT(s2, s1, REG_ITMP1);
1408 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1411 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1412 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1413 M_CMPULT(s1, s2, REG_ITMP3);
1414 M_CMPULT(s2, s1, REG_ITMP1);
1415 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1417 emit_store_dst(jd, iptr, d);
1421 /* floating operations ************************************************/
1423 case ICMD_FNEG: /* ..., value ==> ..., - value */
1425 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1426 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1428 emit_store_dst(jd, iptr, d);
1431 case ICMD_DNEG: /* ..., value ==> ..., - value */
1433 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1434 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1436 emit_store_dst(jd, iptr, d);
1439 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1441 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1442 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1443 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1445 emit_store_dst(jd, iptr, d);
1448 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1450 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1451 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1452 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1454 emit_store_dst(jd, iptr, d);
1457 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1459 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1460 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1461 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1463 emit_store_dst(jd, iptr, d);
1466 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1468 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1469 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1470 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1472 emit_store_dst(jd, iptr, d);
1475 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1477 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1478 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1479 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1481 emit_store_dst(jd, iptr, d);
1484 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1486 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1487 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1488 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1490 emit_store_dst(jd, iptr, d);
1493 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1495 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1496 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1497 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1499 emit_store_dst(jd, iptr, d);
1502 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1504 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1505 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1506 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1508 emit_store_dst(jd, iptr, d);
1512 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1514 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1515 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1516 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1517 M_FDIV(s1,s2, REG_FTMP3);
1518 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1519 M_CVTLF(REG_FTMP3, REG_FTMP3);
1520 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1521 M_FSUB(s1, REG_FTMP3, d);
1522 emit_store_dst(jd, iptr, d);
1525 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1527 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1528 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1529 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1530 M_DDIV(s1,s2, REG_FTMP3);
1531 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1532 M_CVTLD(REG_FTMP3, REG_FTMP3);
1533 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1534 M_DSUB(s1, REG_FTMP3, d);
1535 emit_store_dst(jd, iptr, d);
1539 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1542 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1545 emit_store_dst(jd, iptr, d);
1548 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1550 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1551 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1554 emit_store_dst(jd, iptr, d);
1558 /* XXX these do not work correctly */
1560 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1562 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1563 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1564 M_TRUNCFI(s1, REG_FTMP1);
1565 M_MOVDI(REG_FTMP1, d);
1567 emit_store_dst(jd, iptr, d);
1570 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1572 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1573 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1574 M_TRUNCDI(s1, REG_FTMP1);
1575 M_MOVDI(REG_FTMP1, d);
1577 emit_store_dst(jd, iptr, d);
1580 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1582 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1583 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1584 M_TRUNCFL(s1, REG_FTMP1);
1585 M_MOVDL(REG_FTMP1, d);
1587 emit_store_dst(jd, iptr, d);
1590 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1592 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1594 M_TRUNCDL(s1, REG_FTMP1);
1595 M_MOVDL(REG_FTMP1, d);
1597 emit_store_dst(jd, iptr, d);
1601 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1603 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1604 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1606 emit_store_dst(jd, iptr, d);
1609 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1611 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1612 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1614 emit_store_dst(jd, iptr, d);
1617 #if SUPPORT_FLOAT_CMP
1618 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1620 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1621 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1622 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1625 M_AADD_IMM(REG_ZERO, 1, d);
1629 M_ASUB_IMM(REG_ZERO, 1, d);
1630 M_CMOVT(REG_ZERO, d);
1631 emit_store_dst(jd, iptr, d);
1634 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1636 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1637 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1641 M_ASUB_IMM(REG_ZERO, 1, d);
1645 M_AADD_IMM(REG_ZERO, 1, d);
1646 M_CMOVT(REG_ZERO, d);
1647 emit_store_dst(jd, iptr, d);
1651 #if SUPPORT_DOUBLE_CMP
1652 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1654 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1655 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1656 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1659 M_AADD_IMM(REG_ZERO, 1, d);
1663 M_ASUB_IMM(REG_ZERO, 1, d);
1664 M_CMOVT(REG_ZERO, d);
1665 emit_store_dst(jd, iptr, d);
1668 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1670 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1671 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1672 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1675 M_ASUB_IMM(REG_ZERO, 1, d);
1679 M_AADD_IMM(REG_ZERO, 1, d);
1680 M_CMOVT(REG_ZERO, d);
1681 emit_store_dst(jd, iptr, d);
1686 /* memory operations **************************************************/
1688 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1692 /* implicit null-pointer check */
1693 M_ILD(d, s1, OFFSET(java_array_t, size));
1694 emit_store_dst(jd, iptr, d);
1697 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1701 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1702 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1703 M_AADD(s2, s1, REG_ITMP3);
1704 /* implicit null-pointer check */
1705 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1706 emit_store_dst(jd, iptr, d);
1709 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1711 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1712 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1714 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1715 M_AADD(s2, s1, REG_ITMP3);
1716 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1717 /* implicit null-pointer check */
1718 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1719 emit_store_dst(jd, iptr, d);
1722 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1724 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1725 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1727 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1728 M_AADD(s2, s1, REG_ITMP3);
1729 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1730 /* implicit null-pointer check */
1731 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1732 emit_store_dst(jd, iptr, d);
1735 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1738 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1739 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1740 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1741 M_ASLL_IMM(s2, 2, REG_ITMP3);
1742 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1743 /* implicit null-pointer check */
1744 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1745 emit_store_dst(jd, iptr, d);
1748 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1750 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1751 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1752 #if SIZEOF_VOID_P == 8
1753 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1755 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1757 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1758 M_ASLL_IMM(s2, 3, REG_ITMP3);
1759 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1760 /* implicit null-pointer check */
1761 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1762 emit_store_dst(jd, iptr, d);
1765 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1767 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1768 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1769 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1770 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1771 M_ASLL_IMM(s2, 2, REG_ITMP3);
1772 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1773 /* implicit null-pointer check */
1774 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1775 emit_store_dst(jd, iptr, d);
1778 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1780 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1781 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1782 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1783 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1784 M_ASLL_IMM(s2, 3, REG_ITMP3);
1785 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1786 /* implicit null-pointer check */
1787 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1788 emit_store_dst(jd, iptr, d);
1791 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1795 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1796 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1797 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1798 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1799 /* implicit null-pointer check */
1800 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1801 emit_store_dst(jd, iptr, d);
1805 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1807 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1808 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1809 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1810 M_AADD(s2, s1, REG_ITMP1);
1811 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1812 /* implicit null-pointer check */
1813 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1816 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1817 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1820 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1821 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1822 M_AADD(s2, s1, REG_ITMP1);
1823 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1824 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1825 /* implicit null-pointer check */
1826 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1829 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1831 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1832 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1833 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1834 M_ASLL_IMM(s2, 2, REG_ITMP2);
1835 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1836 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1837 /* implicit null-pointer check */
1838 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1841 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1843 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1844 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1845 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1846 M_ASLL_IMM(s2, 3, REG_ITMP2);
1847 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1848 #if SIZEOF_VOID_P == 8
1849 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1851 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1853 /* implicit null-pointer check */
1854 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1857 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1861 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1862 M_ASLL_IMM(s2, 2, REG_ITMP2);
1863 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1864 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1865 /* implicit null-pointer check */
1866 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1869 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1871 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1872 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1873 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1874 M_ASLL_IMM(s2, 3, REG_ITMP2);
1875 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1876 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1877 /* implicit null-pointer check */
1878 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1882 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1884 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1885 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1886 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1887 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1889 M_INTMOVE(s1, REG_A0);
1890 M_INTMOVE(s3, REG_A1);
1891 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1892 M_ALD(REG_ITMP3, REG_PV, disp);
1893 M_JSR(REG_RA, REG_ITMP3);
1895 emit_arraystore_check(cd, iptr);
1897 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1898 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1899 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1900 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1901 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1902 /* implicit null-pointer check */
1903 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1907 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1909 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1910 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1911 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1912 M_AADD(s2, s1, REG_ITMP1);
1913 /* implicit null-pointer check */
1914 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1917 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1918 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1921 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1922 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1923 M_AADD(s2, s1, REG_ITMP1);
1924 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1925 /* implicit null-pointer check */
1926 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1929 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1932 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1933 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1934 M_ASLL_IMM(s2, 2, REG_ITMP2);
1935 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1936 /* implicit null-pointer check */
1937 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1940 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1942 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1943 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1944 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1945 M_ASLL_IMM(s2, 3, REG_ITMP2);
1946 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1947 /* implicit null-pointer check */
1948 #if SIZEOF_VOID_P == 8
1949 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1951 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1955 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1957 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1958 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1959 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1960 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1961 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1962 /* implicit null-pointer check */
1963 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1967 case ICMD_GETSTATIC: /* ... ==> ..., value */
1969 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1970 uf = iptr->sx.s23.s3.uf;
1971 fieldtype = uf->fieldref->parseddesc.fd->type;
1972 disp = dseg_add_unique_address(cd, uf);
1974 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1977 fi = iptr->sx.s23.s3.fmiref->p.field;
1978 fieldtype = fi->type;
1979 disp = dseg_add_address(cd, fi->value);
1981 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1982 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1986 M_ALD(REG_ITMP1, REG_PV, disp);
1988 switch (fieldtype) {
1990 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1991 M_ILD_INTERN(d, REG_ITMP1, 0);
1994 #if SIZEOF_VOID_P == 8
1995 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1997 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
1999 M_LLD_INTERN(d, REG_ITMP1, 0);
2002 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2003 M_ALD_INTERN(d, REG_ITMP1, 0);
2006 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2007 M_FLD_INTERN(d, REG_ITMP1, 0);
2010 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2011 M_DLD_INTERN(d, REG_ITMP1, 0);
2014 emit_store_dst(jd, iptr, d);
2017 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2019 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2020 uf = iptr->sx.s23.s3.uf;
2021 fieldtype = uf->fieldref->parseddesc.fd->type;
2022 disp = dseg_add_unique_address(cd, uf);
2024 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2027 fi = iptr->sx.s23.s3.fmiref->p.field;
2028 fieldtype = fi->type;
2029 disp = dseg_add_address(cd, fi->value);
2031 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2032 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2036 M_ALD(REG_ITMP1, REG_PV, disp);
2038 switch (fieldtype) {
2040 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2041 M_IST_INTERN(s1, REG_ITMP1, 0);
2044 #if SIZEOF_VOID_P == 8
2045 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2047 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2049 M_LST_INTERN(s1, REG_ITMP1, 0);
2052 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2053 M_AST_INTERN(s1, REG_ITMP1, 0);
2056 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2057 M_FST_INTERN(s1, REG_ITMP1, 0);
2060 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2061 M_DST_INTERN(s1, REG_ITMP1, 0);
2066 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2068 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2069 uf = iptr->sx.s23.s3.uf;
2070 fieldtype = uf->fieldref->parseddesc.fd->type;
2071 disp = dseg_add_unique_address(cd, uf);
2073 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2076 fi = iptr->sx.s23.s3.fmiref->p.field;
2077 fieldtype = fi->type;
2078 disp = dseg_add_address(cd, fi->value);
2080 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2081 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2085 M_ALD(REG_ITMP1, REG_PV, disp);
2087 switch (fieldtype) {
2089 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2092 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2095 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2098 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2101 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2107 case ICMD_GETFIELD: /* ... ==> ..., value */
2109 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2110 emit_nullpointer_check(cd, iptr, s1);
2112 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2113 uf = iptr->sx.s23.s3.uf;
2114 fieldtype = uf->fieldref->parseddesc.fd->type;
2117 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2120 fi = iptr->sx.s23.s3.fmiref->p.field;
2121 fieldtype = fi->type;
2125 switch (fieldtype) {
2127 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2131 #if SIZEOF_VOID_P == 8
2132 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2135 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2136 M_LLD_GETFIELD(d, s1, disp);
2140 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2144 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2148 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2152 emit_store_dst(jd, iptr, d);
2155 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2157 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2158 emit_nullpointer_check(cd, iptr, s1);
2160 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2161 uf = iptr->sx.s23.s3.uf;
2162 fieldtype = uf->fieldref->parseddesc.fd->type;
2166 fi = iptr->sx.s23.s3.fmiref->p.field;
2167 fieldtype = fi->type;
2171 #if SIZEOF_VOID_P == 8
2172 if (IS_INT_LNG_TYPE(fieldtype))
2173 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2175 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2177 if (IS_INT_LNG_TYPE(fieldtype)) {
2178 if (IS_2_WORD_TYPE(fieldtype))
2179 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2181 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2184 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2187 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2188 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2190 switch (fieldtype) {
2192 M_IST(s2, s1, disp);
2195 M_LST(s2, s1, disp);
2198 M_AST(s2, s1, disp);
2201 M_FST(s2, s1, disp);
2204 M_DST(s2, s1, disp);
2209 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2211 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2212 emit_nullpointer_check(cd, iptr, s1);
2214 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2215 uf = iptr->sx.s23.s3.uf;
2216 fieldtype = uf->fieldref->parseddesc.fd->type;
2219 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2222 fi = iptr->sx.s23.s3.fmiref->p.field;
2223 fieldtype = fi->type;
2227 switch (fieldtype) {
2229 M_IST(REG_ZERO, s1, disp);
2232 M_LST(REG_ZERO, s1, disp);
2235 M_AST(REG_ZERO, s1, disp);
2238 M_FST(REG_ZERO, s1, disp);
2241 M_DST(REG_ZERO, s1, disp);
2247 /* branch operations **************************************************/
2249 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2251 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2252 M_INTMOVE(s1, REG_ITMP1_XPTR);
2254 #ifdef ENABLE_VERIFIER
2255 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2256 uc = iptr->sx.s23.s2.uc;
2258 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2260 #endif /* ENABLE_VERIFIER */
2262 disp = dseg_add_functionptr(cd, asm_handle_exception);
2263 M_ALD(REG_ITMP2, REG_PV, disp);
2264 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2266 M_NOP; /* nop ensures that XPC is less than the end */
2267 /* of basic block */
2271 case ICMD_GOTO: /* ... ==> ... */
2272 case ICMD_RET: /* ... ==> ... */
2274 emit_br(cd, iptr->dst.block);
2278 case ICMD_JSR: /* ... ==> ... */
2280 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2284 case ICMD_IFNULL: /* ..., value ==> ... */
2285 case ICMD_IFNONNULL:
2287 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2288 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2291 case ICMD_IFEQ: /* ..., value ==> ... */
2293 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2294 if (iptr->sx.val.i == 0)
2295 emit_beqz(cd, iptr->dst.block, s1);
2297 ICONST(REG_ITMP2, iptr->sx.val.i);
2298 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2302 case ICMD_IFLT: /* ..., value ==> ... */
2304 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2305 if (iptr->sx.val.i == 0)
2306 emit_bltz(cd, iptr->dst.block, s1);
2308 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2309 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2311 ICONST(REG_ITMP2, iptr->sx.val.i);
2312 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2314 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2318 case ICMD_IFLE: /* ..., value ==> ... */
2320 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2321 if (iptr->sx.val.i == 0)
2322 emit_blez(cd, iptr->dst.block, s1);
2324 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2325 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2326 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2329 ICONST(REG_ITMP2, iptr->sx.val.i);
2330 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2331 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2336 case ICMD_IFNE: /* ..., value ==> ... */
2338 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2339 if (iptr->sx.val.i == 0)
2340 emit_bnez(cd, iptr->dst.block, s1);
2342 ICONST(REG_ITMP2, iptr->sx.val.i);
2343 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2347 case ICMD_IFGT: /* ..., value ==> ... */
2349 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2350 if (iptr->sx.val.i == 0)
2351 emit_bgtz(cd, iptr->dst.block, s1);
2353 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2354 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2355 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2358 ICONST(REG_ITMP2, iptr->sx.val.i);
2359 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2360 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2365 case ICMD_IFGE: /* ..., value ==> ... */
2367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2368 if (iptr->sx.val.i == 0)
2369 emit_bgez(cd, iptr->dst.block, s1);
2371 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2372 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2374 ICONST(REG_ITMP2, iptr->sx.val.i);
2375 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2377 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2381 case ICMD_IF_LEQ: /* ..., value ==> ... */
2383 #if SIZEOF_VOID_P == 8
2384 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2385 if (iptr->sx.val.l == 0)
2386 emit_beqz(cd, iptr->dst.block, s1);
2388 LCONST(REG_ITMP2, iptr->sx.val.l);
2389 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2392 if (iptr->sx.val.l == 0) {
2393 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2394 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2395 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2398 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2399 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2400 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2401 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2402 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2403 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2404 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2405 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2410 case ICMD_IF_LLT: /* ..., value ==> ... */
2412 #if SIZEOF_VOID_P == 8
2413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2414 if (iptr->sx.val.l == 0)
2415 emit_bltz(cd, iptr->dst.block, s1);
2417 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2418 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2420 LCONST(REG_ITMP2, iptr->sx.val.l);
2421 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2423 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2426 if (iptr->sx.val.l == 0) {
2427 /* if high word is less than zero, the whole long is too */
2428 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2429 emit_bltz(cd, iptr->dst.block, s1);
2432 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2433 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2434 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2435 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2436 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2437 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2439 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2440 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2441 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2446 case ICMD_IF_LLE: /* ..., value ==> ... */
2448 #if SIZEOF_VOID_P == 8
2449 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2450 if (iptr->sx.val.l == 0)
2451 emit_blez(cd, iptr->dst.block, s1);
2453 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2454 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2455 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2458 LCONST(REG_ITMP2, iptr->sx.val.l);
2459 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2460 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2464 if (iptr->sx.val.l == 0) {
2465 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2466 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2468 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2469 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2472 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2473 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2474 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2475 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2476 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2477 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2479 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2480 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2481 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2486 case ICMD_IF_LNE: /* ..., value ==> ... */
2488 #if SIZEOF_VOID_P == 8
2489 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2490 if (iptr->sx.val.l == 0)
2491 emit_bnez(cd, iptr->dst.block, s1);
2493 LCONST(REG_ITMP2, iptr->sx.val.l);
2494 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2497 if (iptr->sx.val.l == 0) {
2498 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2499 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2500 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2503 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2504 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2505 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2506 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2507 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2508 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2509 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2510 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2515 case ICMD_IF_LGT: /* ..., value ==> ... */
2517 #if SIZEOF_VOID_P == 8
2518 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2519 if (iptr->sx.val.l == 0)
2520 emit_bgtz(cd, iptr->dst.block, s1);
2522 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2523 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2524 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2527 LCONST(REG_ITMP2, iptr->sx.val.l);
2528 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2529 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2533 if (iptr->sx.val.l == 0) {
2534 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2535 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2536 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2538 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2541 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2542 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2543 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2544 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2545 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2546 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2548 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2549 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2550 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2555 case ICMD_IF_LGE: /* ..., value ==> ... */
2557 #if SIZEOF_VOID_P == 8
2558 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2559 if (iptr->sx.val.l == 0)
2560 emit_bgez(cd, iptr->dst.block, s1);
2562 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2563 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2566 LCONST(REG_ITMP2, iptr->sx.val.l);
2567 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2569 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2572 if (iptr->sx.val.l == 0) {
2573 /* if high word is greater equal zero, the whole long is too */
2574 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2575 emit_bgez(cd, iptr->dst.block, s1);
2578 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2579 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2580 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2581 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2582 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2583 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2585 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2586 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2587 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2592 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2593 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2594 #if SIZEOF_VOID_P == 8
2595 case ICMD_IF_LCMPEQ:
2598 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2599 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2600 emit_beq(cd, iptr->dst.block, s1, s2);
2603 #if SIZEOF_VOID_P == 4
2604 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2605 /* op1 = target JavaVM pc */
2607 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2608 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2609 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2611 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2612 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2613 emit_beq(cd, iptr->dst.block, s1, s2);
2617 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2618 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2619 #if SIZEOF_VOID_P == 8
2620 case ICMD_IF_LCMPNE:
2623 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2624 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2625 emit_bne(cd, iptr->dst.block, s1, s2);
2628 #if SIZEOF_VOID_P == 4
2629 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2631 /* TODO: could be optimized (XOR or SUB) */
2632 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2633 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2634 emit_bne(cd, iptr->dst.block, s1, s2);
2635 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2636 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2637 emit_bne(cd, iptr->dst.block, s1, s2);
2641 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2642 #if SIZEOF_VOID_P == 8
2643 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2647 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2648 M_CMPLT(s1, s2, REG_ITMP3);
2649 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2652 #if SIZEOF_VOID_P == 4
2653 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2655 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2656 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2657 M_CMPLT(s1, s2, REG_ITMP3);
2658 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2659 M_CMPGT(s1, s2, REG_ITMP3);
2660 /* load low-bits before the branch, so we know the distance */
2661 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2662 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2663 M_BNEZ(REG_ITMP3, 4); /* XXX */
2665 M_CMPULT(s1, s2, REG_ITMP3);
2666 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2670 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2671 #if SIZEOF_VOID_P == 8
2672 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2676 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2677 M_CMPGT(s1, s2, REG_ITMP3);
2678 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2681 #if SIZEOF_VOID_P == 4
2682 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2684 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2685 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2686 M_CMPGT(s1, s2, REG_ITMP3);
2687 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2688 M_CMPLT(s1, s2, REG_ITMP3);
2689 /* load low-bits before the branch, so we know the distance */
2690 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2691 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2692 M_BNEZ(REG_ITMP3, 4); /* XXX */
2694 M_CMPUGT(s1, s2, REG_ITMP3);
2695 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2699 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2700 #if SIZEOF_VOID_P == 8
2701 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2704 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2705 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2706 M_CMPGT(s1, s2, REG_ITMP3);
2707 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2710 #if SIZEOF_VOID_P == 4
2711 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2713 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2714 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2715 M_CMPLT(s1, s2, REG_ITMP3);
2716 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2717 M_CMPGT(s1, s2, REG_ITMP3);
2718 /* load low-bits before the branch, so we know the distance */
2719 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2720 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2721 M_BNEZ(REG_ITMP3, 4); /* XXX */
2723 M_CMPUGT(s1, s2, REG_ITMP3);
2724 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2728 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2729 #if SIZEOF_VOID_P == 8
2730 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2734 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2735 M_CMPLT(s1, s2, REG_ITMP3);
2736 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2739 #if SIZEOF_VOID_P == 4
2740 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2742 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2743 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2744 M_CMPGT(s1, s2, REG_ITMP3);
2745 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2746 M_CMPLT(s1, s2, REG_ITMP3);
2747 /* load low-bits before the branch, so we know the distance */
2748 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2749 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2750 M_BNEZ(REG_ITMP3, 4); /* XXX */
2752 M_CMPULT(s1, s2, REG_ITMP3);
2753 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2757 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2758 #if SIZEOF_VOID_P == 8
2762 REPLACEMENT_POINT_RETURN(cd, iptr);
2763 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2764 M_INTMOVE(s1, REG_RESULT);
2765 goto nowperformreturn;
2767 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2769 REPLACEMENT_POINT_RETURN(cd, iptr);
2770 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2771 M_INTMOVE(s1, REG_RESULT);
2773 #ifdef ENABLE_VERIFIER
2774 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2775 uc = iptr->sx.s23.s2.uc;
2777 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2779 #endif /* ENABLE_VERIFIER */
2780 goto nowperformreturn;
2782 #if SIZEOF_VOID_P == 4
2783 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2785 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2786 M_LNGMOVE(s1, REG_RESULT_PACKED);
2787 goto nowperformreturn;
2790 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2791 REPLACEMENT_POINT_RETURN(cd, iptr);
2792 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2793 M_FLTMOVE(s1, REG_FRESULT);
2794 goto nowperformreturn;
2796 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2798 REPLACEMENT_POINT_RETURN(cd, iptr);
2799 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2800 M_DBLMOVE(s1, REG_FRESULT);
2801 goto nowperformreturn;
2803 case ICMD_RETURN: /* ... ==> ... */
2805 REPLACEMENT_POINT_RETURN(cd, iptr);
2811 p = cd->stackframesize;
2813 #if !defined(NDEBUG)
2814 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2815 emit_verbosecall_exit(jd);
2818 #if defined(ENABLE_THREADS)
2819 if (checksync && code_is_synchronized(code)) {
2820 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2821 M_ALD(REG_ITMP3, REG_PV, disp);
2823 /* we need to save the proper return value */
2825 switch (iptr->opc) {
2828 #if SIZEOF_VOID_P == 8
2831 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2832 M_JSR(REG_RA, REG_ITMP3);
2833 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2835 #if SIZEOF_VOID_P == 4
2837 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2838 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2839 M_JSR(REG_RA, REG_ITMP3);
2845 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2846 M_JSR(REG_RA, REG_ITMP3);
2847 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2850 M_JSR(REG_RA, REG_ITMP3);
2851 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2855 /* and now restore the proper return value */
2857 switch (iptr->opc) {
2860 #if SIZEOF_VOID_P == 8
2863 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2865 #if SIZEOF_VOID_P == 4
2867 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2872 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2878 /* restore return address */
2880 if (!code_is_leafmethod(code)) {
2881 p--; M_ALD(REG_RA, REG_SP, p * 8);
2884 /* restore saved registers */
2886 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2887 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2889 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2890 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2893 /* deallocate stack and return */
2895 if (cd->stackframesize) {
2898 disp = cd->stackframesize * 8;
2899 lo = (short) (disp);
2900 hi = (short) (((disp) - lo) >> 16);
2904 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2906 M_LUI(REG_ITMP3,hi);
2907 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2909 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2922 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2925 branch_target_t *table;
2927 table = iptr->dst.table;
2929 l = iptr->sx.s23.s2.tablelow;
2930 i = iptr->sx.s23.s3.tablehigh;
2932 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2934 {M_INTMOVE(s1, REG_ITMP1);}
2935 else if (l <= 32768) {
2936 M_IADD_IMM(s1, -l, REG_ITMP1);
2939 ICONST(REG_ITMP2, l);
2940 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2943 /* number of targets */
2948 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2949 emit_beqz(cd, table[0].block, REG_ITMP2);
2951 /* build jump table top down and use address of lowest entry */
2956 dseg_add_target(cd, table->block);
2961 /* length of dataseg after last dseg_add_target is used by load */
2963 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2964 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2965 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2972 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2975 lookup_target_t *lookup;
2977 lookup = iptr->dst.lookup;
2979 i = iptr->sx.s23.s2.lookupcount;
2981 MCODECHECK((i<<2)+8);
2982 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2985 ICONST(REG_ITMP2, lookup->value);
2986 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
2990 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2996 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2998 bte = iptr->sx.s23.s3.bte;
3002 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3004 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3005 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3006 case ICMD_INVOKEINTERFACE:
3008 REPLACEMENT_POINT_INVOKE(cd, iptr);
3010 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3012 um = iptr->sx.s23.s3.um;
3013 md = um->methodref->parseddesc.md;
3016 lm = iptr->sx.s23.s3.fmiref->p.method;
3018 md = lm->parseddesc;
3022 s3 = md->paramcount;
3024 MCODECHECK((s3 << 1) + 64);
3026 /* copy arguments to registers or stack location */
3028 for (s3 = s3 - 1; s3 >= 0; s3--) {
3029 var = VAR(iptr->sx.s23.s2.args[s3]);
3030 d = md->params[s3].regoff;
3032 if (var->flags & PREALLOC)
3035 if (IS_INT_LNG_TYPE(var->type)) {
3036 #if SIZEOF_VOID_P == 8
3037 if (!md->params[s3].inmemory) {
3038 s1 = emit_load(jd, iptr, var, d);
3042 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3043 M_LST(s1, REG_SP, d);
3046 if (!md->params[s3].inmemory) {
3047 s1 = emit_load(jd, iptr, var, d);
3049 if (IS_2_WORD_TYPE(var->type))
3055 if (IS_2_WORD_TYPE(var->type)) {
3056 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3057 M_LST(s1, REG_SP, d);
3060 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3061 M_IST(s1, REG_SP, d);
3067 if (!md->params[s3].inmemory) {
3068 s1 = emit_load(jd, iptr, var, d);
3069 if (IS_2_WORD_TYPE(var->type))
3075 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3076 if (IS_2_WORD_TYPE(var->type))
3077 M_DST(s1, REG_SP, d);
3079 M_FST(s1, REG_SP, d);
3084 switch (iptr->opc) {
3086 if (bte->stub == NULL) {
3087 disp = dseg_add_functionptr(cd, bte->fp);
3088 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3090 /* generate the actual call */
3092 /* TWISTI: i actually don't know the reason for using
3093 REG_ITMP3 here instead of REG_PV. */
3095 M_JSR(REG_RA, REG_ITMP3);
3099 disp = dseg_add_functionptr(cd, bte->stub);
3100 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3102 /* generate the actual call */
3104 M_JSR(REG_RA, REG_PV);
3108 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3109 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3110 M_LDA(REG_PV, REG_RA, -disp);
3113 case ICMD_INVOKESPECIAL:
3114 emit_nullpointer_check(cd, iptr, REG_A0);
3117 case ICMD_INVOKESTATIC:
3119 disp = dseg_add_unique_address(cd, um);
3121 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3125 disp = dseg_add_address(cd, lm->stubroutine);
3127 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3129 /* generate the actual call */
3131 M_JSR(REG_RA, REG_PV);
3133 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3134 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3135 M_LDA(REG_PV, REG_RA, -disp);
3138 case ICMD_INVOKEVIRTUAL:
3139 emit_nullpointer_check(cd, iptr, REG_A0);
3142 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3147 s1 = OFFSET(vftbl_t, table[0]) +
3148 sizeof(methodptr) * lm->vftblindex;
3150 /* implicit null-pointer check */
3151 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3152 M_ALD(REG_PV, REG_METHODPTR, s1);
3154 /* generate the actual call */
3156 M_JSR(REG_RA, REG_PV);
3158 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3159 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3160 M_LDA(REG_PV, REG_RA, -disp);
3163 case ICMD_INVOKEINTERFACE:
3164 emit_nullpointer_check(cd, iptr, REG_A0);
3167 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3173 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3174 sizeof(methodptr*) * lm->class->index;
3176 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3179 /* implicit null-pointer check */
3180 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3181 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3182 M_ALD(REG_PV, REG_METHODPTR, s2);
3184 /* generate the actual call */
3186 M_JSR(REG_RA, REG_PV);
3188 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3189 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3190 M_LDA(REG_PV, REG_RA, -disp);
3194 /* store return value */
3196 d = md->returntype.type;
3198 if (d != TYPE_VOID) {
3199 if (IS_INT_LNG_TYPE(d)) {
3200 #if SIZEOF_VOID_P == 8
3201 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3202 M_INTMOVE(REG_RESULT, s1);
3204 if (IS_2_WORD_TYPE(d)) {
3205 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3206 M_LNGMOVE(REG_RESULT_PACKED, s1);
3209 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3210 M_INTMOVE(REG_RESULT, s1);
3215 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3216 if (IS_2_WORD_TYPE(d))
3217 M_DMOV(REG_FRESULT, s1);
3219 M_FMOV(REG_FRESULT, s1);
3221 emit_store_dst(jd, iptr, s1);
3226 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3228 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3232 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3237 super = iptr->sx.s23.s3.c.cls;
3238 superindex = super->index;
3241 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3242 CODEGEN_CRITICAL_SECTION_NEW;
3244 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3246 /* if class is not resolved, check which code to call */
3248 if (super == NULL) {
3249 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3251 cr = iptr->sx.s23.s3.c.ref;
3252 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3254 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3257 M_ILD(REG_ITMP2, REG_PV, disp);
3258 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3259 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3262 /* interface checkcast code */
3264 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3265 if (super == NULL) {
3266 cr = iptr->sx.s23.s3.c.ref;
3268 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3272 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3275 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3276 M_ILD(REG_ITMP3, REG_ITMP2,
3277 OFFSET(vftbl_t, interfacetablelength));
3278 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3279 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3281 M_ALD(REG_ITMP3, REG_ITMP2,
3282 OFFSET(vftbl_t, interfacetable[0]) -
3283 superindex * sizeof(methodptr*));
3284 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3287 emit_label_br(cd, BRANCH_LABEL_4);
3289 emit_label(cd, BRANCH_LABEL_3);
3292 /* class checkcast code */
3294 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3295 if (super == NULL) {
3296 emit_label(cd, BRANCH_LABEL_2);
3298 cr = iptr->sx.s23.s3.c.ref;
3299 disp = dseg_add_unique_address(cd, NULL);
3301 patcher_add_patch_ref(jd,
3302 PATCHER_resolve_classref_to_vftbl,
3306 disp = dseg_add_address(cd, super->vftbl);
3308 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3311 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3312 M_ALD(REG_ITMP3, REG_PV, disp);
3314 CODEGEN_CRITICAL_SECTION_START;
3316 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3317 /* if (s1 != REG_ITMP1) { */
3318 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3319 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3320 /* #if defined(ENABLE_THREADS) */
3321 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3323 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3325 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3326 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3327 M_ALD(REG_ITMP3, REG_PV, disp);
3328 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3330 CODEGEN_CRITICAL_SECTION_END;
3333 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3334 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3337 emit_label(cd, BRANCH_LABEL_5);
3340 if (super == NULL) {
3341 emit_label(cd, BRANCH_LABEL_1);
3342 emit_label(cd, BRANCH_LABEL_4);
3345 d = codegen_reg_of_dst(jd, iptr, s1);
3348 s1 = emit_load_s1(jd, iptr, REG_A0);
3349 M_INTMOVE(s1, REG_A0);
3351 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3352 cr = iptr->sx.s23.s3.c.ref;
3353 disp = dseg_add_unique_address(cd, NULL);
3355 patcher_add_patch_ref(jd,
3356 PATCHER_resolve_classref_to_classinfo,
3360 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3363 M_ALD(REG_A1, REG_PV, disp);
3364 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3365 M_ALD(REG_ITMP3, REG_PV, disp);
3366 M_JSR(REG_RA, REG_ITMP3);
3369 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3370 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3372 d = codegen_reg_of_dst(jd, iptr, s1);
3376 emit_store_dst(jd, iptr, d);
3379 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3385 super = iptr->sx.s23.s3.c.cls;
3387 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3392 super = iptr->sx.s23.s3.c.cls;
3393 superindex = super->index;
3396 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3397 CODEGEN_CRITICAL_SECTION_NEW;
3399 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3400 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3403 M_MOV(s1, REG_ITMP1);
3409 /* if class is not resolved, check which code to call */
3411 if (super == NULL) {
3412 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3414 cr = iptr->sx.s23.s3.c.ref;
3415 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3417 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3420 M_ILD(REG_ITMP3, REG_PV, disp);
3421 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3422 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3425 /* interface instanceof code */
3427 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3428 if (super == NULL) {
3429 cr = iptr->sx.s23.s3.c.ref;
3431 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3435 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3438 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3439 M_ILD(REG_ITMP3, REG_ITMP1,
3440 OFFSET(vftbl_t, interfacetablelength));
3441 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3442 M_BLEZ(REG_ITMP3, 3);
3444 M_ALD(REG_ITMP1, REG_ITMP1,
3445 OFFSET(vftbl_t, interfacetable[0]) -
3446 superindex * sizeof(methodptr*));
3447 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3450 emit_label_br(cd, BRANCH_LABEL_4);
3452 emit_label(cd, BRANCH_LABEL_3);
3455 /* class instanceof code */
3457 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3458 if (super == NULL) {
3459 emit_label(cd, BRANCH_LABEL_2);
3461 cr = iptr->sx.s23.s3.c.ref;
3462 disp = dseg_add_unique_address(cd, NULL);
3464 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3468 disp = dseg_add_address(cd, super->vftbl);
3470 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3473 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3474 M_ALD(REG_ITMP2, REG_PV, disp);
3476 CODEGEN_CRITICAL_SECTION_START;
3478 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3479 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3480 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3482 CODEGEN_CRITICAL_SECTION_END;
3484 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3485 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3489 emit_label(cd, BRANCH_LABEL_5);
3492 if (super == NULL) {
3493 emit_label(cd, BRANCH_LABEL_1);
3494 emit_label(cd, BRANCH_LABEL_4);
3497 emit_store_dst(jd, iptr, d);
3501 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3503 /* check for negative sizes and copy sizes to stack if necessary */
3505 MCODECHECK((iptr->s1.argcount << 1) + 64);
3507 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3509 var = VAR(iptr->sx.s23.s2.args[s1]);
3511 /* copy SAVEDVAR sizes to stack */
3513 if (!(var->flags & PREALLOC)) {
3514 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3515 #if SIZEOF_VOID_P == 8
3516 M_LST(s2, REG_SP, s1 * 8);
3518 M_IST(s2, REG_SP, (s1 + 2) * 8);
3523 /* a0 = dimension count */
3525 ICONST(REG_A0, iptr->s1.argcount);
3527 /* is patcher function set? */
3529 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3530 cr = iptr->sx.s23.s3.c.ref;
3531 disp = dseg_add_unique_address(cd, NULL);
3533 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3537 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3540 /* a1 = arraydescriptor */
3542 M_ALD(REG_A1, REG_PV, disp);
3544 /* a2 = pointer to dimensions = stack pointer */
3546 #if SIZEOF_VOID_P == 8
3547 M_MOV(REG_SP, REG_A2);
3549 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3552 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3553 M_ALD(REG_ITMP3, REG_PV, disp);
3554 M_JSR(REG_RA, REG_ITMP3);
3557 /* check for exception before result assignment */
3559 emit_exception_check(cd, iptr);
3561 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3562 M_INTMOVE(REG_RESULT, d);
3563 emit_store_dst(jd, iptr, d);
3567 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3572 } /* for instruction */
3574 MCODECHECK(64); /* XXX require smaller number? */
3576 /* At the end of a basic block we may have to append some nops,
3577 because the patcher stub calling code might be longer than the
3578 actual instruction. So codepatching does not change the
3579 following block unintentionally. */
3581 if (cd->mcodeptr < cd->lastmcodeptr) {
3582 while (cd->mcodeptr < cd->lastmcodeptr)
3586 } /* if (bptr -> flags >= BBREACHED) */
3587 } /* for basic block */
3589 /* generate traps */
3591 emit_patcher_traps(jd);
3593 /* everything's ok */
3599 /* codegen_emit_stub_compiler **************************************************
3601 Emits a stub routine which calls the compiler.
3603 *******************************************************************************/
3605 void codegen_emit_stub_compiler(jitdata *jd)
3610 /* get required compiler data */
3615 /* code for the stub */
3617 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3618 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3624 /* codegen_emit_stub_native ****************************************************
3626 Emits a stub routine which calls a native method.
3628 *******************************************************************************/
3630 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3641 /* get required compiler data */
3647 /* initialize variables */
3651 /* calculate stack frame size */
3653 cd->stackframesize =
3654 1 + /* return address */
3655 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3656 sizeof(localref_table) / SIZEOF_VOID_P +
3657 md->paramcount + /* for saving arguments over calls */
3658 #if SIZEOF_VOID_P == 4
3659 5 + /* additional save space (MIPS32) */
3661 1 + /* for saving return address */
3664 /* adjust stackframe size for 16-byte alignment */
3666 if (cd->stackframesize & 1)
3667 cd->stackframesize++;
3669 /* create method header */
3671 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3672 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3673 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3674 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3675 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3677 /* generate stub code */
3679 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3680 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3682 #if !defined(NDEBUG)
3683 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3684 emit_verbosecall_enter(jd);
3687 /* save integer and float argument registers */
3689 #if SIZEOF_VOID_P == 8
3690 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3691 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3692 s1 = md->params[i].regoff;
3693 M_AST(s1, REG_SP, j * 8);
3698 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3699 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3700 if (!md->params[i].inmemory) {
3701 s1 = md->params[i].regoff;
3703 if (IS_2_WORD_TYPE(md->params[i].type))
3704 M_LST(s1, REG_SP, j * 8);
3706 M_IST(s1, REG_SP, j * 8);
3714 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3715 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3716 s1 = md->params[i].regoff;
3718 if (IS_2_WORD_TYPE(md->params[i].type))
3719 M_DST(s1, REG_SP, j * 8);
3721 M_FST(s1, REG_SP, j * 8);
3727 /* prepare data structures for native function call */
3729 M_MOV(REG_SP, REG_A0);
3730 M_MOV(REG_PV, REG_A1);
3731 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3732 M_ALD(REG_ITMP3, REG_PV, disp);
3733 M_JSR(REG_RA, REG_ITMP3);
3734 M_NOP; /* XXX fill me! */
3736 /* remember class argument */
3738 if (m->flags & ACC_STATIC)
3739 M_MOV(REG_RESULT, REG_ITMP3);
3741 /* restore integer and float argument registers */
3743 #if SIZEOF_VOID_P == 8
3744 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3745 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3746 s1 = md->params[i].regoff;
3747 M_LLD(s1, REG_SP, j * 8);
3752 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3753 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3754 if (!md->params[i].inmemory) {
3755 s1 = md->params[i].regoff;
3757 if (IS_2_WORD_TYPE(md->params[i].type))
3758 M_LLD(s1, REG_SP, j * 8);
3760 M_ILD(s1, REG_SP, j * 8);
3768 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3769 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3770 s1 = md->params[i].regoff;
3772 if (IS_2_WORD_TYPE(md->params[i].type))
3773 M_DLD(s1, REG_SP, j * 8);
3775 M_FLD(s1, REG_SP, j * 8);
3781 /* copy or spill arguments to new locations */
3783 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3784 t = md->params[i].type;
3786 if (IS_INT_LNG_TYPE(t)) {
3787 if (!md->params[i].inmemory) {
3788 s1 = md->params[i].regoff;
3789 s2 = nmd->params[j].regoff;
3791 if (!nmd->params[j].inmemory) {
3792 #if SIZEOF_VOID_P == 8
3795 if (IS_2_WORD_TYPE(t))
3802 #if SIZEOF_VOID_P == 8
3803 M_LST(s1, REG_SP, s2);
3805 if (IS_2_WORD_TYPE(t))
3806 M_LST(s1, REG_SP, s2);
3808 M_IST(s1, REG_SP, s2);
3813 s1 = md->params[i].regoff + cd->stackframesize * 8;
3814 s2 = nmd->params[j].regoff;
3816 #if SIZEOF_VOID_P == 8
3817 M_LLD(REG_ITMP1, REG_SP, s1);
3818 M_LST(REG_ITMP1, REG_SP, s2);
3820 if (IS_2_WORD_TYPE(t)) {
3821 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3822 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3825 M_ILD(REG_ITMP1, REG_SP, s1);
3826 M_IST(REG_ITMP1, REG_SP, s2);
3832 if (!md->params[i].inmemory) {
3833 s1 = md->params[i].regoff;
3834 s2 = nmd->params[j].regoff;
3836 if (!nmd->params[j].inmemory) {
3837 #if SIZEOF_VOID_P == 8
3838 if (IS_2_WORD_TYPE(t))
3843 /* On MIPS32 float arguments for native functions
3844 can never be in float argument registers, since
3845 the first argument is _always_ an integer
3846 argument (JNIEnv) */
3848 if (IS_2_WORD_TYPE(t)) {
3849 /* double high/low order is endian
3850 independent: even numbered holds low
3851 32-bits, odd numbered high 32-bits */
3853 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3854 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3861 #if SIZEOF_VOID_P == 8
3862 if (IS_2_WORD_TYPE(t))
3863 M_DST(s1, REG_SP, s2);
3865 M_FST(s1, REG_SP, s2);
3867 /* s1 may have been originally in 2 int registers,
3868 but was moved out by the native function
3869 argument(s), just get low register */
3871 if (IS_2_WORD_TYPE(t))
3872 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3874 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3879 s1 = md->params[i].regoff + cd->stackframesize * 8;
3880 s2 = nmd->params[j].regoff;
3882 #if SIZEOF_VOID_P == 8
3883 if (IS_2_WORD_TYPE(t)) {
3884 M_DLD(REG_FTMP1, REG_SP, s1);
3885 M_DST(REG_FTMP1, REG_SP, s2);
3888 M_FLD(REG_FTMP1, REG_SP, s1);
3889 M_FST(REG_FTMP1, REG_SP, s2);
3892 if (IS_2_WORD_TYPE(t)) {
3893 M_DLD(REG_FTMP1, REG_SP, s1);
3894 M_DST(REG_FTMP1, REG_SP, s2);
3897 M_FLD(REG_FTMP1, REG_SP, s1);
3898 M_FST(REG_FTMP1, REG_SP, s2);
3905 /* Handle native Java methods. */
3907 if (m->flags & ACC_NATIVE) {
3908 /* put class into second argument register */
3910 if (m->flags & ACC_STATIC)
3911 M_MOV(REG_ITMP3, REG_A1);
3913 /* put env into first argument register */
3915 disp = dseg_add_address(cd, _Jv_env);
3916 M_ALD(REG_A0, REG_PV, disp);
3919 /* Call the native function. */
3921 disp = dseg_add_functionptr(cd, f);
3922 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3923 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3924 M_NOP; /* delay slot */
3926 /* save return value */
3928 switch (md->returntype.type) {
3929 #if SIZEOF_VOID_P == 8
3933 M_LST(REG_RESULT, REG_SP, 0 * 8);
3937 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3942 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3945 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3949 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3956 #if !defined(NDEBUG)
3957 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3958 emit_verbosecall_exit(jd);
3961 /* remove native stackframe info */
3963 M_MOV(REG_SP, REG_A0);
3964 M_MOV(REG_PV, REG_A1);
3965 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3966 M_ALD(REG_ITMP3, REG_PV, disp);
3967 M_JSR(REG_RA, REG_ITMP3);
3968 M_NOP; /* XXX fill me! */
3969 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3971 /* restore return value */
3973 switch (md->returntype.type) {
3974 #if SIZEOF_VOID_P == 8
3978 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3982 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3987 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3990 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3994 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
4001 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4003 /* check for exception */
4005 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4006 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4008 M_RET(REG_RA); /* return to caller */
4009 M_NOP; /* DELAY SLOT */
4011 /* handle exception */
4013 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4014 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4015 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4016 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4018 /* Generate patcher traps. */
4020 emit_patcher_traps(jd);
4025 * These are local overrides for various environment variables in Emacs.
4026 * Please do not remove this and leave it at the end of the file, where
4027 * Emacs will automagically detect them.
4028 * ---------------------------------------------------------------------
4031 * indent-tabs-mode: t
4035 * vim:noexpandtab:sw=4:ts=4: