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/md.h"
58 #include "vm/jit/patcher-common.h"
59 #include "vm/jit/reg.h"
60 #include "vm/jit/replace.h"
62 #if defined(ENABLE_LSRA)
63 # include "vm/jit/allocator/lsra.h"
66 #include "vmcore/class.h"
67 #include "vmcore/options.h"
70 /* codegen_emit ****************************************************************
72 Generates machine code.
74 *******************************************************************************/
76 bool codegen_emit(jitdata *jd)
82 s4 len, s1, s2, s3, d, disp;
87 constant_classref *cr;
89 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
90 unresolved_method *um;
91 builtintable_entry *bte;
98 /* get required compiler data */
105 /* prevent compiler warnings */
120 savedregs_num = code_is_leafmethod(code) ? 0 : 1; /* space to save the RA */
122 /* space to save used callee saved registers */
124 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
125 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
127 cd->stackframesize = rd->memuse + savedregs_num;
129 #if defined(ENABLE_THREADS)
130 /* space to save argument of monitor_enter */
132 if (checksync && code_is_synchronized(code)) {
133 # if SIZEOF_VOID_P == 8
134 cd->stackframesize++;
137 cd->stackframesize += 2;
142 /* keep stack 16-byte aligned */
144 if (cd->stackframesize & 1)
145 cd->stackframesize++;
147 /* create method header */
149 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
150 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
152 code->synchronizedoffset = rd->memuse * 8;
154 /* REMOVEME: We still need it for exception handling in assembler. */
156 if (code_is_leafmethod(code))
157 (void) dseg_add_unique_s4(cd, 1);
159 (void) dseg_add_unique_s4(cd, 0);
161 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
162 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
164 dseg_addlinenumbertablesize(cd);
166 /* create stack frame (if necessary) */
168 if (cd->stackframesize)
169 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
171 /* save return address and used callee saved registers */
173 p = cd->stackframesize;
174 if (!code_is_leafmethod(code)) {
175 p--; M_AST(REG_RA, REG_SP, p * 8);
177 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
178 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
180 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
181 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
184 /* take arguments out of register or stack frame */
188 for (p = 0, l = 0; p < md->paramcount; p++) {
189 t = md->paramtypes[p].type;
191 varindex = jd->local_map[l * 5 + t];
194 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
197 if (varindex == UNUSED)
201 s1 = md->params[p].regoff;
203 if (IS_INT_LNG_TYPE(t)) { /* integer args */
204 if (!md->params[p].inmemory) { /* register arguments */
205 #if SIZEOF_VOID_P == 8
206 if (!(var->flags & INMEMORY))
207 M_INTMOVE(s1, var->vv.regoff);
209 M_LST(s1, REG_SP, var->vv.regoff);
211 if (!(var->flags & INMEMORY)) {
212 if (IS_2_WORD_TYPE(t))
213 M_LNGMOVE(s1, var->vv.regoff);
215 M_INTMOVE(s1, var->vv.regoff);
218 if (IS_2_WORD_TYPE(t))
219 M_LST(s1, REG_SP, var->vv.regoff);
221 M_IST(s1, REG_SP, var->vv.regoff);
225 else { /* stack arguments */
226 if (!(var->flags & INMEMORY)) {
227 #if SIZEOF_VOID_P == 8
228 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
230 if (IS_2_WORD_TYPE(t))
231 M_LLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
233 M_ILD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
237 var->vv.regoff = cd->stackframesize * 8 + s1;
240 else { /* floating args */
241 if (!md->params[p].inmemory) {
242 if (!(var->flags & INMEMORY)) {
243 if (IS_2_WORD_TYPE(t))
244 M_DBLMOVE(s1, var->vv.regoff);
246 M_FLTMOVE(s1, var->vv.regoff);
249 if (IS_2_WORD_TYPE(t))
250 M_DST(s1, REG_SP, var->vv.regoff);
252 M_FST(s1, REG_SP, var->vv.regoff);
256 if (!(var->flags & INMEMORY)) {
257 if (IS_2_WORD_TYPE(t))
258 M_DLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
260 M_FLD(var->vv.regoff, REG_SP, cd->stackframesize * 8 + s1);
263 var->vv.regoff = cd->stackframesize * 8 + s1;
268 /* call monitorenter function */
270 #if defined(ENABLE_THREADS)
271 if (checksync && code_is_synchronized(code)) {
272 /* stack offset for monitor argument */
276 # if !defined(NDEBUG)
277 if (opt_verbosecall) {
278 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
280 for (p = 0; p < INT_ARG_CNT; p++)
281 M_AST(abi_registers_integer_argument[p], REG_SP, p * 8);
283 for (p = 0; p < FLT_ARG_CNT; p++)
284 M_DST(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
286 s1 += INT_ARG_CNT + FLT_ARG_CNT;
290 /* get correct lock object */
292 if (m->flags & ACC_STATIC) {
293 disp = dseg_add_address(cd, &m->class->object.header);
294 M_ALD(REG_A0, REG_PV, disp);
295 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
296 M_ALD(REG_ITMP3, REG_PV, disp);
299 /* emit_nullpointer_check(cd, iptr, REG_A0); */
301 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
302 M_ALD(REG_ITMP3, REG_PV, disp); /* branch delay */
303 M_ALD_INTERN(REG_ZERO, REG_ZERO, EXCEPTION_HARDWARE_NULLPOINTER);
306 M_JSR(REG_RA, REG_ITMP3);
307 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
309 # if !defined(NDEBUG)
310 if (opt_verbosecall) {
311 for (p = 0; p < INT_ARG_CNT; p++)
312 M_ALD(abi_registers_integer_argument[p], REG_SP, p * 8);
314 for (p = 0; p < FLT_ARG_CNT; p++)
315 M_DLD(abi_registers_float_argument[p], REG_SP, (INT_ARG_CNT + p) * 8);
318 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
326 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
327 emit_verbosecall_enter(jd);
330 /* end of header generation */
332 /* create replacement points */
334 REPLACEMENT_POINTS_INIT(cd, jd);
336 /* walk through all basic blocks */
338 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
340 /* handle replacement points */
342 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
344 /* store relative start of block */
346 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
348 if (bptr->flags >= BBREACHED) {
349 /* branch resolving */
351 codegen_resolve_branchrefs(cd, bptr);
353 /* copy interface registers to their destination */
357 #if defined(ENABLE_LSRA)
361 src = bptr->invars[len];
362 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
363 /* d = reg_of_var(m, src, REG_ITMP1); */
364 if (!(src->flags & INMEMORY))
368 M_INTMOVE(REG_ITMP1, d);
369 emit_store(jd, NULL, src, d);
376 var = VAR(bptr->invars[len]);
377 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
378 d = codegen_reg_of_var(0, var, REG_ITMP1);
379 M_INTMOVE(REG_ITMP1, d);
380 emit_store(jd, NULL, var, d);
383 assert((var->flags & INOUT));
386 #if defined(ENABLE_LSRA)
389 /* walk through all instructions */
392 /* currentline = 0; */
394 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
395 if (iptr->line != currentline) {
396 dseg_addlinenumber(cd, iptr->line);
397 currentline = iptr->line;
400 MCODECHECK(64); /* an instruction usually needs < 64 words */
404 case ICMD_NOP: /* ... ==> ... */
405 case ICMD_POP: /* ..., value ==> ... */
406 case ICMD_POP2: /* ..., value, value ==> ... */
409 case ICMD_INLINE_START:
411 REPLACEMENT_POINT_INLINE_START(cd, iptr);
414 case ICMD_INLINE_BODY:
416 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
417 dseg_addlinenumber_inline_start(cd, iptr);
418 dseg_addlinenumber(cd, iptr->line);
421 case ICMD_INLINE_END:
423 dseg_addlinenumber_inline_end(cd, iptr);
424 dseg_addlinenumber(cd, iptr->line);
427 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
429 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
430 emit_nullpointer_check(cd, iptr, s1);
433 /* constant operations ************************************************/
435 case ICMD_ICONST: /* ... ==> ..., constant */
437 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
438 ICONST(d, iptr->sx.val.i);
439 emit_store_dst(jd, iptr, d);
442 case ICMD_LCONST: /* ... ==> ..., constant */
444 #if SIZEOF_VOID_P == 8
445 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
447 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
449 LCONST(d, iptr->sx.val.l);
450 emit_store_dst(jd, iptr, d);
453 case ICMD_FCONST: /* ... ==> ..., constant */
455 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
456 disp = dseg_add_float(cd, iptr->sx.val.f);
457 M_FLD(d, REG_PV, disp);
458 emit_store_dst(jd, iptr, d);
461 case ICMD_DCONST: /* ... ==> ..., constant */
463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
464 disp = dseg_add_double(cd, iptr->sx.val.d);
465 M_DLD(d, REG_PV, disp);
466 emit_store_dst(jd, iptr, d);
469 case ICMD_ACONST: /* ... ==> ..., constant */
471 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
473 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
474 cr = iptr->sx.val.c.ref;
475 disp = dseg_add_unique_address(cd, cr);
477 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
480 M_ALD(d, REG_PV, disp);
483 if (iptr->sx.val.anyptr == NULL)
484 M_INTMOVE(REG_ZERO, d);
486 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
487 M_ALD(d, REG_PV, disp);
490 emit_store_dst(jd, iptr, d);
494 /* load/store/copy/move operations ************************************/
496 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
501 case ICMD_ISTORE: /* ..., value ==> ... */
512 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
517 /* integer operations *************************************************/
519 case ICMD_INEG: /* ..., value ==> ..., - value */
521 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
523 M_ISUB(REG_ZERO, s1, d);
524 emit_store_dst(jd, iptr, d);
527 case ICMD_LNEG: /* ..., value ==> ..., - value */
529 #if SIZEOF_VOID_P == 8
530 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
531 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
532 M_LSUB(REG_ZERO, s1, d);
534 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
535 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
536 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
537 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
538 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
539 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
541 emit_store_dst(jd, iptr, d);
544 case ICMD_I2L: /* ..., value ==> ..., value */
546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
547 #if SIZEOF_VOID_P == 8
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
551 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
552 M_INTMOVE(s1, GET_LOW_REG(d));
553 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
555 emit_store_dst(jd, iptr, d);
558 case ICMD_L2I: /* ..., value ==> ..., value */
560 #if SIZEOF_VOID_P == 8
561 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
562 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
563 M_ISLL_IMM(s1, 0, d);
565 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
566 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
567 M_INTMOVE(GET_LOW_REG(s1), d);
569 emit_store_dst(jd, iptr, d);
572 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
574 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
575 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
576 #if SIZEOF_VOID_P == 8
577 M_LSLL_IMM(s1, 56, d);
578 M_LSRA_IMM( d, 56, d);
580 M_ISLL_IMM(s1, 24, d);
581 M_ISRA_IMM( d, 24, d);
583 emit_store_dst(jd, iptr, d);
586 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
588 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
589 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
590 M_AND_IMM(s1, 0xffff, d);
591 emit_store_dst(jd, iptr, d);
594 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
596 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
597 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
598 #if SIZEOF_VOID_P == 8
599 M_LSLL_IMM(s1, 48, d);
600 M_LSRA_IMM( d, 48, d);
602 M_ISLL_IMM(s1, 16, d);
603 M_ISRA_IMM( d, 16, d);
605 emit_store_dst(jd, iptr, d);
609 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
612 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
613 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
615 emit_store_dst(jd, iptr, d);
619 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
620 /* sx.val.i = constant */
622 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
624 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
625 M_IADD_IMM(s1, iptr->sx.val.i, d);
627 ICONST(REG_ITMP2, iptr->sx.val.i);
628 M_IADD(s1, REG_ITMP2, d);
630 emit_store_dst(jd, iptr, d);
633 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
635 #if SIZEOF_VOID_P == 8
636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
637 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
638 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
641 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
642 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
643 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
644 M_IADD(s1, s2, GET_HIGH_REG(d));
645 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
646 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
647 if (s1 == GET_LOW_REG(d)) {
648 M_MOV(s1, REG_ITMP3);
651 M_IADD(s1, s2, GET_LOW_REG(d));
652 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
653 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
655 emit_store_dst(jd, iptr, d);
658 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
659 /* sx.val.l = constant */
661 #if SIZEOF_VOID_P == 8
662 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
663 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
664 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
665 M_LADD_IMM(s1, iptr->sx.val.l, d);
667 LCONST(REG_ITMP2, iptr->sx.val.l);
668 M_LADD(s1, REG_ITMP2, d);
671 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
672 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
673 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
674 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
675 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
676 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
678 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
679 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
680 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
681 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
682 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
683 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
684 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
687 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
688 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
689 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
690 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
691 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
692 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
693 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
694 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
697 emit_store_dst(jd, iptr, d);
700 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
702 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
703 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
704 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
706 emit_store_dst(jd, iptr, d);
709 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
710 /* sx.val.i = constant */
712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
713 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
714 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
715 M_IADD_IMM(s1, -iptr->sx.val.i, d);
717 ICONST(REG_ITMP2, iptr->sx.val.i);
718 M_ISUB(s1, REG_ITMP2, d);
720 emit_store_dst(jd, iptr, d);
723 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
725 #if SIZEOF_VOID_P == 8
726 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
727 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
728 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
731 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
732 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
733 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
734 M_ISUB(s1, s2, GET_HIGH_REG(d));
735 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
736 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
737 M_CMPULT(s1, s2, REG_ITMP3);
738 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
739 /* if s1 is equal to REG_ITMP3 we have to reload it, since
740 the CMPULT instruction destroyed it */
742 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
743 M_ISUB(s1, s2, GET_LOW_REG(d));
746 emit_store_dst(jd, iptr, d);
749 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
750 /* sx.val.l = constant */
752 #if SIZEOF_VOID_P == 8
753 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
755 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
756 M_LADD_IMM(s1, -iptr->sx.val.l, d);
758 LCONST(REG_ITMP2, iptr->sx.val.l);
759 M_LSUB(s1, REG_ITMP2, d);
762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
763 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
764 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
765 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
766 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
767 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
768 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
769 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
771 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
772 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
773 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
774 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
775 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
778 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
779 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
780 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
781 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
782 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
783 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
784 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
785 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
788 emit_store_dst(jd, iptr, d);
791 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
793 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
794 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
795 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
800 emit_store_dst(jd, iptr, d);
803 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
804 /* sx.val.i = constant */
806 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
807 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
808 ICONST(REG_ITMP2, iptr->sx.val.i);
809 M_IMUL(s1, REG_ITMP2);
813 emit_store_dst(jd, iptr, d);
816 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
818 #if SIZEOF_VOID_P == 8
819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
820 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
827 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
828 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
829 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
834 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
836 M_MFHI(GET_HIGH_REG(d));
837 M_MFLO(GET_LOW_REG(d));
840 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
842 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
843 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
846 /* XXX do we need nops here? */
848 emit_store_dst(jd, iptr, d);
851 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
852 /* sx.val.l = constant */
854 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
855 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
856 LCONST(REG_ITMP2, iptr->sx.val.l);
857 M_LMUL(s1, REG_ITMP2);
861 emit_store_dst(jd, iptr, d);
864 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
866 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
867 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
868 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
869 emit_arithmetic_check(cd, iptr, s2);
874 emit_store_dst(jd, iptr, d);
877 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
879 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
880 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
881 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
882 emit_arithmetic_check(cd, iptr, s2);
887 emit_store_dst(jd, iptr, d);
890 #if SIZEOF_VOID_P == 8
892 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
896 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
897 emit_arithmetic_check(cd, iptr, s2);
902 emit_store_dst(jd, iptr, d);
905 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
907 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
908 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
909 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
910 emit_arithmetic_check(cd, iptr, s2);
915 emit_store_dst(jd, iptr, d);
918 #else /* SIZEOF_VOID_P == 8 */
920 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
921 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
923 s1 = emit_load_s1(jd, iptr, REG_A0_A1_PACKED);
924 s2 = emit_load_s2(jd, iptr, REG_A2_A3_PACKED);
926 /* XXX TODO: only do this if arithmetic check is really done! */
927 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
928 emit_arithmetic_check(cd, iptr, REG_ITMP3);
930 M_LNGMOVE(s1, REG_A0_A1_PACKED);
931 M_LNGMOVE(s2, REG_A2_A3_PACKED);
933 bte = iptr->sx.s23.s3.bte;
934 disp = dseg_add_functionptr(cd, bte->fp);
935 M_ALD(REG_ITMP3, REG_PV, disp);
936 M_JSR(REG_RA, REG_ITMP3);
939 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
940 M_LNGMOVE(REG_RESULT_PACKED, d);
941 emit_store_dst(jd, iptr, d);
944 #endif /* SIZEOF_VOID_P == 8 */
946 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
947 /* val.i = constant */
949 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
950 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
951 #if SIZEOF_VOID_P == 8
952 M_LSRA_IMM(s1, 63, REG_ITMP2);
953 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
954 M_LADD(s1, REG_ITMP2, REG_ITMP2);
955 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
957 M_ISRA_IMM(s1, 31, REG_ITMP2);
958 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
959 M_IADD(s1, REG_ITMP2, REG_ITMP2);
960 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
962 emit_store_dst(jd, iptr, d);
965 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
966 /* val.i = constant */
968 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
969 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
971 M_MOV(s1, REG_ITMP1);
974 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
975 M_AND_IMM(s1, iptr->sx.val.i, d);
978 M_ISUB(REG_ZERO, s1, d);
979 M_AND_IMM(d, iptr->sx.val.i, d);
982 ICONST(REG_ITMP2, iptr->sx.val.i);
983 M_AND(s1, REG_ITMP2, d);
986 M_ISUB(REG_ZERO, s1, d);
987 M_AND(d, REG_ITMP2, d);
989 M_ISUB(REG_ZERO, d, d);
990 emit_store_dst(jd, iptr, d);
993 #if SIZEOF_VOID_P == 8
995 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
996 /* val.i = constant */
998 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
999 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1000 M_LSRA_IMM(s1, 63, REG_ITMP2);
1001 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1002 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1003 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1004 emit_store_dst(jd, iptr, d);
1007 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1008 /* val.l = constant */
1010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1011 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1013 M_MOV(s1, REG_ITMP1);
1016 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1017 M_AND_IMM(s1, iptr->sx.val.l, d);
1020 M_LSUB(REG_ZERO, s1, d);
1021 M_AND_IMM(d, iptr->sx.val.l, d);
1024 LCONST(REG_ITMP2, iptr->sx.val.l);
1025 M_AND(s1, REG_ITMP2, d);
1028 M_LSUB(REG_ZERO, s1, d);
1029 M_AND(d, REG_ITMP2, d);
1031 M_LSUB(REG_ZERO, d, d);
1032 emit_store_dst(jd, iptr, d);
1035 #endif /* SIZEOF_VOID_P == 8 */
1037 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1039 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1040 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1041 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1043 emit_store_dst(jd, iptr, d);
1046 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1047 /* sx.val.i = constant */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1051 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1052 emit_store_dst(jd, iptr, d);
1055 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1057 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1058 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1059 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1061 emit_store_dst(jd, iptr, d);
1064 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1065 /* sx.val.i = constant */
1067 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1068 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1069 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1070 emit_store_dst(jd, iptr, d);
1073 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1075 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1076 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1077 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1079 emit_store_dst(jd, iptr, d);
1082 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1083 /* sx.val.i = constant */
1085 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1086 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1087 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1088 emit_store_dst(jd, iptr, d);
1091 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1093 #if SIZEOF_VOID_P == 8
1094 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1095 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1096 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1099 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1100 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1101 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1103 M_ISLL(s2, 26, REG_ITMP1);
1104 M_BGEZ(REG_ITMP1, 3);
1107 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1109 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1112 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1114 M_BEQZ(REG_ITMP1, 4);
1115 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1117 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1118 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1119 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1122 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1125 emit_store_dst(jd, iptr, d);
1128 #if SIZEOF_VOID_P == 8
1130 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1131 /* sx.val.i = constant */
1133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1134 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1135 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1136 emit_store_dst(jd, iptr, d);
1139 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1141 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1142 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1143 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1145 emit_store_dst(jd, iptr, d);
1148 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1149 /* sx.val.i = constant */
1151 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1152 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1153 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1154 emit_store_dst(jd, iptr, d);
1157 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1159 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1160 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1161 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1163 emit_store_dst(jd, iptr, d);
1166 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1167 /* sx.val.i = constant */
1169 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1170 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1171 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1172 emit_store_dst(jd, iptr, d);
1175 #endif /* SIZEOF_VOID_P == 8 */
1177 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1179 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1180 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1181 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1183 emit_store_dst(jd, iptr, d);
1186 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1187 /* sx.val.i = constant */
1189 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1190 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1191 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1192 M_AND_IMM(s1, iptr->sx.val.i, d);
1194 ICONST(REG_ITMP2, iptr->sx.val.i);
1195 M_AND(s1, REG_ITMP2, d);
1197 emit_store_dst(jd, iptr, d);
1200 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1202 #if SIZEOF_VOID_P == 8
1203 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1204 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1205 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1208 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1209 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1210 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1211 M_AND(s1, s2, GET_LOW_REG(d));
1212 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1213 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1214 M_AND(s1, s2, GET_HIGH_REG(d));
1216 emit_store_dst(jd, iptr, d);
1219 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1220 /* sx.val.l = constant */
1222 #if SIZEOF_VOID_P == 8
1223 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1224 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1225 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1226 M_AND_IMM(s1, iptr->sx.val.l, d);
1228 LCONST(REG_ITMP2, iptr->sx.val.l);
1229 M_AND(s1, REG_ITMP2, d);
1232 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1233 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1234 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1235 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1236 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1239 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1240 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1241 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1242 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1243 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1246 emit_store_dst(jd, iptr, d);
1249 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1251 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1252 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1253 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1255 emit_store_dst(jd, iptr, d);
1258 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1259 /* sx.val.i = constant */
1261 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1262 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1263 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1264 M_OR_IMM(s1, iptr->sx.val.i, d);
1266 ICONST(REG_ITMP2, iptr->sx.val.i);
1267 M_OR(s1, REG_ITMP2, d);
1269 emit_store_dst(jd, iptr, d);
1272 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1274 #if SIZEOF_VOID_P == 8
1275 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1276 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1277 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1280 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1281 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1282 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1283 M_OR(s1, s2, GET_LOW_REG(d));
1284 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1285 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1286 M_OR(s1, s2, GET_HIGH_REG(d));
1288 emit_store_dst(jd, iptr, d);
1291 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1292 /* sx.val.l = constant */
1294 #if SIZEOF_VOID_P == 8
1295 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1296 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1297 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1298 M_OR_IMM(s1, iptr->sx.val.l, d);
1300 LCONST(REG_ITMP2, iptr->sx.val.l);
1301 M_OR(s1, REG_ITMP2, d);
1304 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1305 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1306 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1307 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1308 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1311 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1312 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1313 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1314 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1315 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1318 emit_store_dst(jd, iptr, d);
1321 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1327 emit_store_dst(jd, iptr, d);
1330 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1331 /* sx.val.i = constant */
1333 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1334 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1335 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1336 M_XOR_IMM(s1, iptr->sx.val.i, d);
1338 ICONST(REG_ITMP2, iptr->sx.val.i);
1339 M_XOR(s1, REG_ITMP2, d);
1341 emit_store_dst(jd, iptr, d);
1344 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1346 #if SIZEOF_VOID_P == 8
1347 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1348 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1349 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1352 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1353 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1355 M_XOR(s1, s2, GET_LOW_REG(d));
1356 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1357 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1358 M_XOR(s1, s2, GET_HIGH_REG(d));
1360 emit_store_dst(jd, iptr, d);
1363 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1364 /* sx.val.l = constant */
1366 #if SIZEOF_VOID_P == 8
1367 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1368 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1369 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1370 M_XOR_IMM(s1, iptr->sx.val.l, d);
1372 LCONST(REG_ITMP2, iptr->sx.val.l);
1373 M_XOR(s1, REG_ITMP2, d);
1376 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1377 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1378 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1379 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1380 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1383 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1384 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1385 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1386 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1387 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1390 emit_store_dst(jd, iptr, d);
1394 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1396 #if SIZEOF_VOID_P == 8
1397 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1398 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1399 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1400 M_CMPLT(s1, s2, REG_ITMP3);
1401 M_CMPLT(s2, s1, REG_ITMP1);
1402 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1404 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1405 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1406 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1407 M_CMPLT(s1, s2, REG_ITMP3);
1408 M_CMPLT(s2, s1, REG_ITMP1);
1409 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1412 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1413 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1414 M_CMPULT(s1, s2, REG_ITMP3);
1415 M_CMPULT(s2, s1, REG_ITMP1);
1416 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1418 emit_store_dst(jd, iptr, d);
1422 /* floating operations ************************************************/
1424 case ICMD_FNEG: /* ..., value ==> ..., - value */
1426 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1427 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1429 emit_store_dst(jd, iptr, d);
1432 case ICMD_DNEG: /* ..., value ==> ..., - value */
1434 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1435 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1437 emit_store_dst(jd, iptr, d);
1440 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1442 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1443 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1444 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1446 emit_store_dst(jd, iptr, d);
1449 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1451 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1452 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1453 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1455 emit_store_dst(jd, iptr, d);
1458 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1460 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1461 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1462 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1464 emit_store_dst(jd, iptr, d);
1467 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1469 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1470 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1471 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1473 emit_store_dst(jd, iptr, d);
1476 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1478 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1479 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1480 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1482 emit_store_dst(jd, iptr, d);
1485 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1487 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1488 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1489 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1491 emit_store_dst(jd, iptr, d);
1494 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1496 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1497 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1498 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1500 emit_store_dst(jd, iptr, d);
1503 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1505 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1506 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1507 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1509 emit_store_dst(jd, iptr, d);
1513 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1515 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1516 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1517 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1518 M_FDIV(s1,s2, REG_FTMP3);
1519 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1520 M_CVTLF(REG_FTMP3, REG_FTMP3);
1521 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1522 M_FSUB(s1, REG_FTMP3, d);
1523 emit_store_dst(jd, iptr, d);
1526 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1528 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1529 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1530 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1531 M_DDIV(s1,s2, REG_FTMP3);
1532 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1533 M_CVTLD(REG_FTMP3, REG_FTMP3);
1534 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1535 M_DSUB(s1, REG_FTMP3, d);
1536 emit_store_dst(jd, iptr, d);
1540 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1542 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1543 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1546 emit_store_dst(jd, iptr, d);
1549 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1551 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1552 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1555 emit_store_dst(jd, iptr, d);
1559 /* XXX these do not work correctly */
1561 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1563 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1564 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1565 M_TRUNCFI(s1, REG_FTMP1);
1566 M_MOVDI(REG_FTMP1, d);
1568 emit_store_dst(jd, iptr, d);
1571 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1573 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1574 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1575 M_TRUNCDI(s1, REG_FTMP1);
1576 M_MOVDI(REG_FTMP1, d);
1578 emit_store_dst(jd, iptr, d);
1581 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1583 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1584 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1585 M_TRUNCFL(s1, REG_FTMP1);
1586 M_MOVDL(REG_FTMP1, d);
1588 emit_store_dst(jd, iptr, d);
1591 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1593 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1594 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1595 M_TRUNCDL(s1, REG_FTMP1);
1596 M_MOVDL(REG_FTMP1, d);
1598 emit_store_dst(jd, iptr, d);
1602 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1604 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1605 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1607 emit_store_dst(jd, iptr, d);
1610 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1612 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1613 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1615 emit_store_dst(jd, iptr, d);
1618 #if SUPPORT_FLOAT_CMP
1619 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1621 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1622 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1623 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1626 M_AADD_IMM(REG_ZERO, 1, d);
1630 M_ASUB_IMM(REG_ZERO, 1, d);
1631 M_CMOVT(REG_ZERO, d);
1632 emit_store_dst(jd, iptr, d);
1635 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1637 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1638 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1639 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1642 M_ASUB_IMM(REG_ZERO, 1, d);
1646 M_AADD_IMM(REG_ZERO, 1, d);
1647 M_CMOVT(REG_ZERO, d);
1648 emit_store_dst(jd, iptr, d);
1652 #if SUPPORT_DOUBLE_CMP
1653 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1655 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1656 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1657 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1660 M_AADD_IMM(REG_ZERO, 1, d);
1664 M_ASUB_IMM(REG_ZERO, 1, d);
1665 M_CMOVT(REG_ZERO, d);
1666 emit_store_dst(jd, iptr, d);
1669 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1671 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1672 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1673 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1676 M_ASUB_IMM(REG_ZERO, 1, d);
1680 M_AADD_IMM(REG_ZERO, 1, d);
1681 M_CMOVT(REG_ZERO, d);
1682 emit_store_dst(jd, iptr, d);
1687 /* memory operations **************************************************/
1689 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1693 /* implicit null-pointer check */
1694 M_ILD(d, s1, OFFSET(java_array_t, size));
1695 emit_store_dst(jd, iptr, d);
1698 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1700 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1701 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1703 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1704 M_AADD(s2, s1, REG_ITMP3);
1705 /* implicit null-pointer check */
1706 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray_t, data[0]));
1707 emit_store_dst(jd, iptr, d);
1710 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1712 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1713 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1715 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1716 M_AADD(s2, s1, REG_ITMP3);
1717 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1718 /* implicit null-pointer check */
1719 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray_t, data[0]));
1720 emit_store_dst(jd, iptr, d);
1723 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1726 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1727 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1728 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1729 M_AADD(s2, s1, REG_ITMP3);
1730 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1731 /* implicit null-pointer check */
1732 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray_t, data[0]));
1733 emit_store_dst(jd, iptr, d);
1736 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1739 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1741 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1742 M_ASLL_IMM(s2, 2, REG_ITMP3);
1743 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1744 /* implicit null-pointer check */
1745 M_ILD_INTERN(d, REG_ITMP3, OFFSET(java_intarray_t, data[0]));
1746 emit_store_dst(jd, iptr, d);
1749 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1751 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1752 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1753 #if SIZEOF_VOID_P == 8
1754 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1756 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1758 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1759 M_ASLL_IMM(s2, 3, REG_ITMP3);
1760 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1761 /* implicit null-pointer check */
1762 M_LLD_INTERN(d, REG_ITMP3, OFFSET(java_longarray_t, data[0]));
1763 emit_store_dst(jd, iptr, d);
1766 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1770 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1771 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1772 M_ASLL_IMM(s2, 2, REG_ITMP3);
1773 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1774 /* implicit null-pointer check */
1775 M_FLD_INTERN(d, REG_ITMP3, OFFSET(java_floatarray_t, data[0]));
1776 emit_store_dst(jd, iptr, d);
1779 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1781 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1782 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1783 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1784 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1785 M_ASLL_IMM(s2, 3, REG_ITMP3);
1786 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1787 /* implicit null-pointer check */
1788 M_DLD_INTERN(d, REG_ITMP3, OFFSET(java_doublearray_t, data[0]));
1789 emit_store_dst(jd, iptr, d);
1792 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1794 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1795 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1796 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1797 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1798 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1799 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1800 /* implicit null-pointer check */
1801 M_ALD_INTERN(d, REG_ITMP3, OFFSET(java_objectarray_t, data[0]));
1802 emit_store_dst(jd, iptr, d);
1806 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1808 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1809 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1810 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1811 M_AADD(s2, s1, REG_ITMP1);
1812 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1813 /* implicit null-pointer check */
1814 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1817 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1818 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1822 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1823 M_AADD(s2, s1, REG_ITMP1);
1824 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1825 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1826 /* implicit null-pointer check */
1827 M_SST(s3, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1830 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1832 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1833 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1834 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1835 M_ASLL_IMM(s2, 2, REG_ITMP2);
1836 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1837 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1838 /* implicit null-pointer check */
1839 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1842 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1844 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1845 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1846 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1847 M_ASLL_IMM(s2, 3, REG_ITMP2);
1848 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1849 #if SIZEOF_VOID_P == 8
1850 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1852 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1854 /* implicit null-pointer check */
1855 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1858 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1860 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1861 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1862 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1863 M_ASLL_IMM(s2, 2, REG_ITMP2);
1864 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1865 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1866 /* implicit null-pointer check */
1867 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray_t, data[0]));
1870 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1873 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1874 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1875 M_ASLL_IMM(s2, 3, REG_ITMP2);
1876 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1877 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1878 /* implicit null-pointer check */
1879 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray_t, data[0]));
1883 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1885 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1886 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1887 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1888 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1890 M_INTMOVE(s1, REG_A0);
1891 M_INTMOVE(s3, REG_A1);
1892 disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
1893 M_ALD(REG_ITMP3, REG_PV, disp);
1894 M_JSR(REG_RA, REG_ITMP3);
1896 emit_arraystore_check(cd, iptr);
1898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1900 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1901 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1902 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1903 /* implicit null-pointer check */
1904 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1908 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1910 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1911 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1912 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1913 M_AADD(s2, s1, REG_ITMP1);
1914 /* implicit null-pointer check */
1915 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray_t, data[0]));
1918 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1919 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1921 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1922 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1923 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1924 M_AADD(s2, s1, REG_ITMP1);
1925 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1926 /* implicit null-pointer check */
1927 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray_t, data[0]));
1930 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1932 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1933 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1934 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1935 M_ASLL_IMM(s2, 2, REG_ITMP2);
1936 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1937 /* implicit null-pointer check */
1938 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray_t, data[0]));
1941 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1944 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1945 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1946 M_ASLL_IMM(s2, 3, REG_ITMP2);
1947 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1948 /* implicit null-pointer check */
1949 #if SIZEOF_VOID_P == 8
1950 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1952 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray_t, data[0]));
1956 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1958 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1959 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1960 emit_arrayindexoutofbounds_check(cd, iptr, s1, s2);
1961 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1962 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1963 /* implicit null-pointer check */
1964 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray_t, data[0]));
1968 case ICMD_GETSTATIC: /* ... ==> ..., value */
1970 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1971 uf = iptr->sx.s23.s3.uf;
1972 fieldtype = uf->fieldref->parseddesc.fd->type;
1973 disp = dseg_add_unique_address(cd, uf);
1975 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
1978 fi = iptr->sx.s23.s3.fmiref->p.field;
1979 fieldtype = fi->type;
1980 disp = dseg_add_address(cd, fi->value);
1982 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
1983 patcher_add_patch_ref(jd, PATCHER_initialize_class,
1987 M_ALD(REG_ITMP1, REG_PV, disp);
1989 switch (fieldtype) {
1991 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1992 M_ILD_INTERN(d, REG_ITMP1, 0);
1995 #if SIZEOF_VOID_P == 8
1996 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1998 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2000 M_LLD_INTERN(d, REG_ITMP1, 0);
2003 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2004 M_ALD_INTERN(d, REG_ITMP1, 0);
2007 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2008 M_FLD_INTERN(d, REG_ITMP1, 0);
2011 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2012 M_DLD_INTERN(d, REG_ITMP1, 0);
2015 emit_store_dst(jd, iptr, d);
2018 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2020 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2021 uf = iptr->sx.s23.s3.uf;
2022 fieldtype = uf->fieldref->parseddesc.fd->type;
2023 disp = dseg_add_unique_address(cd, uf);
2025 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2028 fi = iptr->sx.s23.s3.fmiref->p.field;
2029 fieldtype = fi->type;
2030 disp = dseg_add_address(cd, fi->value);
2032 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2033 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2037 M_ALD(REG_ITMP1, REG_PV, disp);
2039 switch (fieldtype) {
2041 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2042 M_IST_INTERN(s1, REG_ITMP1, 0);
2045 #if SIZEOF_VOID_P == 8
2046 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2048 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2050 M_LST_INTERN(s1, REG_ITMP1, 0);
2053 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2054 M_AST_INTERN(s1, REG_ITMP1, 0);
2057 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2058 M_FST_INTERN(s1, REG_ITMP1, 0);
2061 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2062 M_DST_INTERN(s1, REG_ITMP1, 0);
2067 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2069 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2070 uf = iptr->sx.s23.s3.uf;
2071 fieldtype = uf->fieldref->parseddesc.fd->type;
2072 disp = dseg_add_unique_address(cd, uf);
2074 patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
2077 fi = iptr->sx.s23.s3.fmiref->p.field;
2078 fieldtype = fi->type;
2079 disp = dseg_add_address(cd, fi->value);
2081 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2082 patcher_add_patch_ref(jd, PATCHER_initialize_class,
2086 M_ALD(REG_ITMP1, REG_PV, disp);
2088 switch (fieldtype) {
2090 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2093 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2096 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2099 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2102 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2108 case ICMD_GETFIELD: /* ... ==> ..., value */
2110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2111 emit_nullpointer_check(cd, iptr, s1);
2113 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2114 uf = iptr->sx.s23.s3.uf;
2115 fieldtype = uf->fieldref->parseddesc.fd->type;
2118 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2121 fi = iptr->sx.s23.s3.fmiref->p.field;
2122 fieldtype = fi->type;
2126 switch (fieldtype) {
2128 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2132 #if SIZEOF_VOID_P == 8
2133 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2136 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2137 M_LLD_GETFIELD(d, s1, disp);
2141 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2145 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2149 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2153 emit_store_dst(jd, iptr, d);
2156 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2158 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2159 emit_nullpointer_check(cd, iptr, s1);
2161 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2162 uf = iptr->sx.s23.s3.uf;
2163 fieldtype = uf->fieldref->parseddesc.fd->type;
2167 fi = iptr->sx.s23.s3.fmiref->p.field;
2168 fieldtype = fi->type;
2172 #if SIZEOF_VOID_P == 8
2173 if (IS_INT_LNG_TYPE(fieldtype))
2174 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2176 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2178 if (IS_INT_LNG_TYPE(fieldtype)) {
2179 if (IS_2_WORD_TYPE(fieldtype))
2180 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2182 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2185 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2188 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2189 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2191 switch (fieldtype) {
2193 M_IST(s2, s1, disp);
2196 M_LST(s2, s1, disp);
2199 M_AST(s2, s1, disp);
2202 M_FST(s2, s1, disp);
2205 M_DST(s2, s1, disp);
2210 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2213 emit_nullpointer_check(cd, iptr, s1);
2215 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2216 uf = iptr->sx.s23.s3.uf;
2217 fieldtype = uf->fieldref->parseddesc.fd->type;
2220 patcher_add_patch_ref(jd, PATCHER_get_putfield, uf, 0);
2223 fi = iptr->sx.s23.s3.fmiref->p.field;
2224 fieldtype = fi->type;
2228 switch (fieldtype) {
2230 M_IST(REG_ZERO, s1, disp);
2233 M_LST(REG_ZERO, s1, disp);
2236 M_AST(REG_ZERO, s1, disp);
2239 M_FST(REG_ZERO, s1, disp);
2242 M_DST(REG_ZERO, s1, disp);
2248 /* branch operations **************************************************/
2250 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2252 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2253 M_INTMOVE(s1, REG_ITMP1_XPTR);
2255 #ifdef ENABLE_VERIFIER
2256 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2257 uc = iptr->sx.s23.s2.uc;
2259 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2261 #endif /* ENABLE_VERIFIER */
2263 disp = dseg_add_functionptr(cd, asm_handle_exception);
2264 M_ALD(REG_ITMP2, REG_PV, disp);
2265 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2267 M_NOP; /* nop ensures that XPC is less than the end */
2268 /* of basic block */
2272 case ICMD_GOTO: /* ... ==> ... */
2273 case ICMD_RET: /* ... ==> ... */
2275 emit_br(cd, iptr->dst.block);
2279 case ICMD_JSR: /* ... ==> ... */
2281 emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
2285 case ICMD_IFNULL: /* ..., value ==> ... */
2286 case ICMD_IFNONNULL:
2288 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2289 emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
2292 case ICMD_IFEQ: /* ..., value ==> ... */
2294 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2295 if (iptr->sx.val.i == 0)
2296 emit_beqz(cd, iptr->dst.block, s1);
2298 ICONST(REG_ITMP2, iptr->sx.val.i);
2299 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2303 case ICMD_IFLT: /* ..., value ==> ... */
2305 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2306 if (iptr->sx.val.i == 0)
2307 emit_bltz(cd, iptr->dst.block, s1);
2309 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2310 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2312 ICONST(REG_ITMP2, iptr->sx.val.i);
2313 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2315 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2319 case ICMD_IFLE: /* ..., value ==> ... */
2321 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2322 if (iptr->sx.val.i == 0)
2323 emit_blez(cd, iptr->dst.block, s1);
2325 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2326 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2327 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2330 ICONST(REG_ITMP2, iptr->sx.val.i);
2331 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2332 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2337 case ICMD_IFNE: /* ..., value ==> ... */
2339 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2340 if (iptr->sx.val.i == 0)
2341 emit_bnez(cd, iptr->dst.block, s1);
2343 ICONST(REG_ITMP2, iptr->sx.val.i);
2344 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2348 case ICMD_IFGT: /* ..., value ==> ... */
2350 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2351 if (iptr->sx.val.i == 0)
2352 emit_bgtz(cd, iptr->dst.block, s1);
2354 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2355 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2356 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2359 ICONST(REG_ITMP2, iptr->sx.val.i);
2360 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2361 emit_bnez(cd, iptr->dst.block, REG_ITMP1);
2366 case ICMD_IFGE: /* ..., value ==> ... */
2368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2369 if (iptr->sx.val.i == 0)
2370 emit_bgez(cd, iptr->dst.block, s1);
2372 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2373 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2375 ICONST(REG_ITMP2, iptr->sx.val.i);
2376 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2378 emit_beqz(cd, iptr->dst.block, REG_ITMP1);
2382 case ICMD_IF_LEQ: /* ..., value ==> ... */
2384 #if SIZEOF_VOID_P == 8
2385 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2386 if (iptr->sx.val.l == 0)
2387 emit_beqz(cd, iptr->dst.block, s1);
2389 LCONST(REG_ITMP2, iptr->sx.val.l);
2390 emit_beq(cd, iptr->dst.block, s1, REG_ITMP2);
2393 if (iptr->sx.val.l == 0) {
2394 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2395 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2396 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2399 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2400 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2401 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2402 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2403 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2404 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2405 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2406 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2411 case ICMD_IF_LLT: /* ..., value ==> ... */
2413 #if SIZEOF_VOID_P == 8
2414 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2415 if (iptr->sx.val.l == 0)
2416 emit_bltz(cd, iptr->dst.block, s1);
2418 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
2419 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2421 LCONST(REG_ITMP2, iptr->sx.val.l);
2422 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2424 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2427 if (iptr->sx.val.l == 0) {
2428 /* if high word is less than zero, the whole long is too */
2429 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2430 emit_bltz(cd, iptr->dst.block, s1);
2433 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2434 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2435 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2436 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2437 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2438 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2440 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2441 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2442 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2447 case ICMD_IF_LLE: /* ..., value ==> ... */
2449 #if SIZEOF_VOID_P == 8
2450 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2451 if (iptr->sx.val.l == 0)
2452 emit_blez(cd, iptr->dst.block, s1);
2454 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2455 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2456 emit_bnez(cd, iptr->dst.block, REG_ITMP2);
2459 LCONST(REG_ITMP2, iptr->sx.val.l);
2460 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2461 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2465 if (iptr->sx.val.l == 0) {
2466 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2467 M_BGTZ(GET_HIGH_REG(s1), 5); /* XXX */
2469 emit_bltz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2470 emit_beqz(cd, iptr->dst.block, GET_LOW_REG(s1));
2473 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2474 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2475 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2476 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2477 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2478 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2480 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2481 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2482 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2487 case ICMD_IF_LNE: /* ..., value ==> ... */
2489 #if SIZEOF_VOID_P == 8
2490 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2491 if (iptr->sx.val.l == 0)
2492 emit_bnez(cd, iptr->dst.block, s1);
2494 LCONST(REG_ITMP2, iptr->sx.val.l);
2495 emit_bne(cd, iptr->dst.block, s1, REG_ITMP2);
2498 if (iptr->sx.val.l == 0) {
2499 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2500 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2501 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2504 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2505 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2506 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2507 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2508 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2509 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2510 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2511 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2516 case ICMD_IF_LGT: /* ..., value ==> ... */
2518 #if SIZEOF_VOID_P == 8
2519 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2520 if (iptr->sx.val.l == 0)
2521 emit_bgtz(cd, iptr->dst.block, s1);
2523 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2524 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP2);
2525 emit_beqz(cd, iptr->dst.block, REG_ITMP2);
2528 LCONST(REG_ITMP2, iptr->sx.val.l);
2529 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2530 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2534 if (iptr->sx.val.l == 0) {
2535 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2536 emit_bgtz(cd, iptr->dst.block, GET_HIGH_REG(s1));
2537 M_BLTZ(GET_HIGH_REG(s1), 3); /* XXX */
2539 emit_bnez(cd, iptr->dst.block, GET_LOW_REG(s1));
2542 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2543 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2544 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2545 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2546 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2547 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2549 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2550 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2551 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2556 case ICMD_IF_LGE: /* ..., value ==> ... */
2558 #if SIZEOF_VOID_P == 8
2559 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2560 if (iptr->sx.val.l == 0)
2561 emit_bgez(cd, iptr->dst.block, s1);
2563 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2564 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP3);
2567 LCONST(REG_ITMP2, iptr->sx.val.l);
2568 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2570 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2573 if (iptr->sx.val.l == 0) {
2574 /* if high word is greater equal zero, the whole long is too */
2575 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2576 emit_bgez(cd, iptr->dst.block, s1);
2579 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2580 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2581 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2582 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2583 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2584 M_BNE(s1, REG_ITMP2, 5); /* XXX */
2586 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2587 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2588 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2593 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2594 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2595 #if SIZEOF_VOID_P == 8
2596 case ICMD_IF_LCMPEQ:
2599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2600 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2601 emit_beq(cd, iptr->dst.block, s1, s2);
2604 #if SIZEOF_VOID_P == 4
2605 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2606 /* op1 = target JavaVM pc */
2608 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2609 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2610 M_BNE(s1, s2, 3); /* XXX TWISTI: uff, that is a problem */
2612 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2613 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2614 emit_beq(cd, iptr->dst.block, s1, s2);
2618 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2619 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2620 #if SIZEOF_VOID_P == 8
2621 case ICMD_IF_LCMPNE:
2624 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2625 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2626 emit_bne(cd, iptr->dst.block, s1, s2);
2629 #if SIZEOF_VOID_P == 4
2630 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2632 /* TODO: could be optimized (XOR or SUB) */
2633 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2634 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2635 emit_bne(cd, iptr->dst.block, s1, s2);
2636 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2637 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2638 emit_bne(cd, iptr->dst.block, s1, s2);
2642 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2643 #if SIZEOF_VOID_P == 8
2644 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2647 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2648 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2649 M_CMPLT(s1, s2, REG_ITMP3);
2650 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2653 #if SIZEOF_VOID_P == 4
2654 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2656 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2657 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2658 M_CMPLT(s1, s2, REG_ITMP3);
2659 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2660 M_CMPGT(s1, s2, REG_ITMP3);
2661 /* load low-bits before the branch, so we know the distance */
2662 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2663 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2664 M_BNEZ(REG_ITMP3, 4); /* XXX */
2666 M_CMPULT(s1, s2, REG_ITMP3);
2667 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2671 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2672 #if SIZEOF_VOID_P == 8
2673 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2676 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2677 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2678 M_CMPGT(s1, s2, REG_ITMP3);
2679 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2682 #if SIZEOF_VOID_P == 4
2683 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2685 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2686 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2687 M_CMPGT(s1, s2, REG_ITMP3);
2688 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2689 M_CMPLT(s1, s2, REG_ITMP3);
2690 /* load low-bits before the branch, so we know the distance */
2691 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2692 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2693 M_BNEZ(REG_ITMP3, 4); /* XXX */
2695 M_CMPUGT(s1, s2, REG_ITMP3);
2696 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2700 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2701 #if SIZEOF_VOID_P == 8
2702 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2705 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2706 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2707 M_CMPGT(s1, s2, REG_ITMP3);
2708 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2711 #if SIZEOF_VOID_P == 4
2712 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2714 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2715 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2716 M_CMPLT(s1, s2, REG_ITMP3);
2717 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2718 M_CMPGT(s1, s2, REG_ITMP3);
2719 /* load low-bits before the branch, so we know the distance */
2720 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2721 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2722 M_BNEZ(REG_ITMP3, 4); /* XXX */
2724 M_CMPUGT(s1, s2, REG_ITMP3);
2725 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2729 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2730 #if SIZEOF_VOID_P == 8
2731 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2734 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2735 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2736 M_CMPLT(s1, s2, REG_ITMP3);
2737 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2740 #if SIZEOF_VOID_P == 4
2741 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2743 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2744 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2745 M_CMPGT(s1, s2, REG_ITMP3);
2746 emit_bnez(cd, iptr->dst.block, REG_ITMP3);
2747 M_CMPLT(s1, s2, REG_ITMP3);
2748 /* load low-bits before the branch, so we know the distance */
2749 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2750 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2751 M_BNEZ(REG_ITMP3, 4); /* XXX */
2753 M_CMPULT(s1, s2, REG_ITMP3);
2754 emit_beqz(cd, iptr->dst.block, REG_ITMP3);
2758 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2759 #if SIZEOF_VOID_P == 8
2763 REPLACEMENT_POINT_RETURN(cd, iptr);
2764 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2765 M_INTMOVE(s1, REG_RESULT);
2766 goto nowperformreturn;
2768 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2770 REPLACEMENT_POINT_RETURN(cd, iptr);
2771 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2772 M_INTMOVE(s1, REG_RESULT);
2774 #ifdef ENABLE_VERIFIER
2775 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2776 uc = iptr->sx.s23.s2.uc;
2778 patcher_add_patch_ref(jd, PATCHER_resolve_class, uc, 0);
2780 #endif /* ENABLE_VERIFIER */
2781 goto nowperformreturn;
2783 #if SIZEOF_VOID_P == 4
2784 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2786 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2787 M_LNGMOVE(s1, REG_RESULT_PACKED);
2788 goto nowperformreturn;
2791 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2792 REPLACEMENT_POINT_RETURN(cd, iptr);
2793 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2794 M_FLTMOVE(s1, REG_FRESULT);
2795 goto nowperformreturn;
2797 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2799 REPLACEMENT_POINT_RETURN(cd, iptr);
2800 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2801 M_DBLMOVE(s1, REG_FRESULT);
2802 goto nowperformreturn;
2804 case ICMD_RETURN: /* ... ==> ... */
2806 REPLACEMENT_POINT_RETURN(cd, iptr);
2812 p = cd->stackframesize;
2814 #if !defined(NDEBUG)
2815 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2816 emit_verbosecall_exit(jd);
2819 #if defined(ENABLE_THREADS)
2820 if (checksync && code_is_synchronized(code)) {
2821 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2822 M_ALD(REG_ITMP3, REG_PV, disp);
2824 /* we need to save the proper return value */
2826 switch (iptr->opc) {
2829 #if SIZEOF_VOID_P == 8
2832 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2833 M_JSR(REG_RA, REG_ITMP3);
2834 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2836 #if SIZEOF_VOID_P == 4
2838 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2839 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2840 M_JSR(REG_RA, REG_ITMP3);
2846 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2847 M_JSR(REG_RA, REG_ITMP3);
2848 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2851 M_JSR(REG_RA, REG_ITMP3);
2852 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2856 /* and now restore the proper return value */
2858 switch (iptr->opc) {
2861 #if SIZEOF_VOID_P == 8
2864 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2866 #if SIZEOF_VOID_P == 4
2868 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2873 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2879 /* restore return address */
2881 if (!code_is_leafmethod(code)) {
2882 p--; M_ALD(REG_RA, REG_SP, p * 8);
2885 /* restore saved registers */
2887 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2888 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
2890 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2891 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2894 /* deallocate stack and return */
2896 if (cd->stackframesize) {
2899 disp = cd->stackframesize * 8;
2900 lo = (short) (disp);
2901 hi = (short) (((disp) - lo) >> 16);
2905 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2907 M_LUI(REG_ITMP3,hi);
2908 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2910 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2923 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2926 branch_target_t *table;
2928 table = iptr->dst.table;
2930 l = iptr->sx.s23.s2.tablelow;
2931 i = iptr->sx.s23.s3.tablehigh;
2933 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2935 {M_INTMOVE(s1, REG_ITMP1);}
2936 else if (l <= 32768) {
2937 M_IADD_IMM(s1, -l, REG_ITMP1);
2940 ICONST(REG_ITMP2, l);
2941 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
2944 /* number of targets */
2949 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
2950 emit_beqz(cd, table[0].block, REG_ITMP2);
2952 /* build jump table top down and use address of lowest entry */
2957 dseg_add_target(cd, table->block);
2962 /* length of dataseg after last dseg_add_target is used by load */
2964 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1);
2965 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
2966 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
2973 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2976 lookup_target_t *lookup;
2978 lookup = iptr->dst.lookup;
2980 i = iptr->sx.s23.s2.lookupcount;
2982 MCODECHECK((i<<2)+8);
2983 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2986 ICONST(REG_ITMP2, lookup->value);
2987 emit_beq(cd, lookup->target.block, s1, REG_ITMP2);
2991 emit_br(cd, iptr->sx.s23.s3.lookupdefault.block);
2997 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
2999 bte = iptr->sx.s23.s3.bte;
3003 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3005 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3006 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3007 case ICMD_INVOKEINTERFACE:
3009 REPLACEMENT_POINT_INVOKE(cd, iptr);
3011 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3013 um = iptr->sx.s23.s3.um;
3014 md = um->methodref->parseddesc.md;
3017 lm = iptr->sx.s23.s3.fmiref->p.method;
3019 md = lm->parseddesc;
3023 s3 = md->paramcount;
3025 MCODECHECK((s3 << 1) + 64);
3027 /* copy arguments to registers or stack location */
3029 for (s3 = s3 - 1; s3 >= 0; s3--) {
3030 var = VAR(iptr->sx.s23.s2.args[s3]);
3031 d = md->params[s3].regoff;
3033 if (var->flags & PREALLOC)
3036 if (IS_INT_LNG_TYPE(var->type)) {
3037 #if SIZEOF_VOID_P == 8
3038 if (!md->params[s3].inmemory) {
3039 s1 = emit_load(jd, iptr, var, d);
3043 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3044 M_LST(s1, REG_SP, d);
3047 if (!md->params[s3].inmemory) {
3048 s1 = emit_load(jd, iptr, var, d);
3050 if (IS_2_WORD_TYPE(var->type))
3056 if (IS_2_WORD_TYPE(var->type)) {
3057 s1 = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3058 M_LST(s1, REG_SP, d);
3061 s1 = emit_load(jd, iptr, var, REG_ITMP1);
3062 M_IST(s1, REG_SP, d);
3068 if (!md->params[s3].inmemory) {
3069 s1 = emit_load(jd, iptr, var, d);
3070 if (IS_2_WORD_TYPE(var->type))
3076 s1 = emit_load(jd, iptr, var, REG_FTMP1);
3077 if (IS_2_WORD_TYPE(var->type))
3078 M_DST(s1, REG_SP, d);
3080 M_FST(s1, REG_SP, d);
3085 switch (iptr->opc) {
3087 if (bte->stub == NULL) {
3088 disp = dseg_add_functionptr(cd, bte->fp);
3089 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3091 /* generate the actual call */
3093 /* TWISTI: i actually don't know the reason for using
3094 REG_ITMP3 here instead of REG_PV. */
3096 M_JSR(REG_RA, REG_ITMP3);
3100 disp = dseg_add_functionptr(cd, bte->stub);
3101 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3103 /* generate the actual call */
3105 M_JSR(REG_RA, REG_PV);
3109 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3110 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3111 M_LDA(REG_PV, REG_RA, -disp);
3114 case ICMD_INVOKESPECIAL:
3115 emit_nullpointer_check(cd, iptr, REG_A0);
3118 case ICMD_INVOKESTATIC:
3120 disp = dseg_add_unique_address(cd, um);
3122 patcher_add_patch_ref(jd, PATCHER_invokestatic_special, um,
3126 disp = dseg_add_address(cd, lm->stubroutine);
3128 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3130 /* generate the actual call */
3132 M_JSR(REG_RA, REG_PV);
3134 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3135 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3136 M_LDA(REG_PV, REG_RA, -disp);
3139 case ICMD_INVOKEVIRTUAL:
3140 emit_nullpointer_check(cd, iptr, REG_A0);
3143 patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
3148 s1 = OFFSET(vftbl_t, table[0]) +
3149 sizeof(methodptr) * lm->vftblindex;
3151 /* implicit null-pointer check */
3152 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3153 M_ALD(REG_PV, REG_METHODPTR, s1);
3155 /* generate the actual call */
3157 M_JSR(REG_RA, REG_PV);
3159 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3160 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3161 M_LDA(REG_PV, REG_RA, -disp);
3164 case ICMD_INVOKEINTERFACE:
3165 emit_nullpointer_check(cd, iptr, REG_A0);
3168 patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
3174 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3175 sizeof(methodptr*) * lm->class->index;
3177 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3180 /* implicit null-pointer check */
3181 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
3182 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3183 M_ALD(REG_PV, REG_METHODPTR, s2);
3185 /* generate the actual call */
3187 M_JSR(REG_RA, REG_PV);
3189 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3190 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3191 M_LDA(REG_PV, REG_RA, -disp);
3195 /* store return value */
3197 d = md->returntype.type;
3199 if (d != TYPE_VOID) {
3200 if (IS_INT_LNG_TYPE(d)) {
3201 #if SIZEOF_VOID_P == 8
3202 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3203 M_INTMOVE(REG_RESULT, s1);
3205 if (IS_2_WORD_TYPE(d)) {
3206 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3207 M_LNGMOVE(REG_RESULT_PACKED, s1);
3210 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3211 M_INTMOVE(REG_RESULT, s1);
3216 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3217 if (IS_2_WORD_TYPE(d))
3218 M_DMOV(REG_FRESULT, s1);
3220 M_FMOV(REG_FRESULT, s1);
3222 emit_store_dst(jd, iptr, s1);
3227 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3229 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3233 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3238 super = iptr->sx.s23.s3.c.cls;
3239 superindex = super->index;
3242 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3243 CODEGEN_CRITICAL_SECTION_NEW;
3245 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3247 /* if class is not resolved, check which code to call */
3249 if (super == NULL) {
3250 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3252 cr = iptr->sx.s23.s3.c.ref;
3253 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3255 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3258 M_ILD(REG_ITMP2, REG_PV, disp);
3259 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3260 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP2);
3263 /* interface checkcast code */
3265 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3266 if (super == NULL) {
3267 cr = iptr->sx.s23.s3.c.ref;
3269 patcher_add_patch_ref(jd, PATCHER_checkcast_interface,
3273 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3276 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3277 M_ILD(REG_ITMP3, REG_ITMP2,
3278 OFFSET(vftbl_t, interfacetablelength));
3279 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3280 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3282 M_ALD(REG_ITMP3, REG_ITMP2,
3283 OFFSET(vftbl_t, interfacetable[0]) -
3284 superindex * sizeof(methodptr*));
3285 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3288 emit_label_br(cd, BRANCH_LABEL_4);
3290 emit_label(cd, BRANCH_LABEL_3);
3293 /* class checkcast code */
3295 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3296 if (super == NULL) {
3297 emit_label(cd, BRANCH_LABEL_2);
3299 cr = iptr->sx.s23.s3.c.ref;
3300 disp = dseg_add_unique_address(cd, NULL);
3302 patcher_add_patch_ref(jd,
3303 PATCHER_resolve_classref_to_vftbl,
3307 disp = dseg_add_address(cd, super->vftbl);
3309 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3312 M_ALD(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
3313 M_ALD(REG_ITMP3, REG_PV, disp);
3315 CODEGEN_CRITICAL_SECTION_START;
3317 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3318 /* if (s1 != REG_ITMP1) { */
3319 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3320 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3321 /* #if defined(ENABLE_THREADS) */
3322 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3324 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3326 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3327 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3328 M_ALD(REG_ITMP3, REG_PV, disp);
3329 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3331 CODEGEN_CRITICAL_SECTION_END;
3334 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3335 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3338 emit_label(cd, BRANCH_LABEL_5);
3341 if (super == NULL) {
3342 emit_label(cd, BRANCH_LABEL_1);
3343 emit_label(cd, BRANCH_LABEL_4);
3346 d = codegen_reg_of_dst(jd, iptr, s1);
3349 s1 = emit_load_s1(jd, iptr, REG_A0);
3350 M_INTMOVE(s1, REG_A0);
3352 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3353 cr = iptr->sx.s23.s3.c.ref;
3354 disp = dseg_add_unique_address(cd, NULL);
3356 patcher_add_patch_ref(jd,
3357 PATCHER_resolve_classref_to_classinfo,
3361 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3364 M_ALD(REG_A1, REG_PV, disp);
3365 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3366 M_ALD(REG_ITMP3, REG_PV, disp);
3367 M_JSR(REG_RA, REG_ITMP3);
3370 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3371 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3373 d = codegen_reg_of_dst(jd, iptr, s1);
3377 emit_store_dst(jd, iptr, d);
3380 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3386 super = iptr->sx.s23.s3.c.cls;
3388 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3393 super = iptr->sx.s23.s3.c.cls;
3394 superindex = super->index;
3397 if ((super == NULL) || !(super->flags & ACC_INTERFACE))
3398 CODEGEN_CRITICAL_SECTION_NEW;
3400 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3404 M_MOV(s1, REG_ITMP1);
3410 /* if class is not resolved, check which code to call */
3412 if (super == NULL) {
3413 emit_label_beqz(cd, BRANCH_LABEL_1, s1);
3415 cr = iptr->sx.s23.s3.c.ref;
3416 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3418 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_flags,
3421 M_ILD(REG_ITMP3, REG_PV, disp);
3422 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3423 emit_label_beqz(cd, BRANCH_LABEL_2, REG_ITMP3);
3426 /* interface instanceof code */
3428 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3429 if (super == NULL) {
3430 cr = iptr->sx.s23.s3.c.ref;
3432 patcher_add_patch_ref(jd, PATCHER_instanceof_interface,
3436 emit_label_beqz(cd, BRANCH_LABEL_3, s1);
3439 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3440 M_ILD(REG_ITMP3, REG_ITMP1,
3441 OFFSET(vftbl_t, interfacetablelength));
3442 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3443 M_BLEZ(REG_ITMP3, 3);
3445 M_ALD(REG_ITMP1, REG_ITMP1,
3446 OFFSET(vftbl_t, interfacetable[0]) -
3447 superindex * sizeof(methodptr*));
3448 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3451 emit_label_br(cd, BRANCH_LABEL_4);
3453 emit_label(cd, BRANCH_LABEL_3);
3456 /* class instanceof code */
3458 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3459 if (super == NULL) {
3460 emit_label(cd, BRANCH_LABEL_2);
3462 cr = iptr->sx.s23.s3.c.ref;
3463 disp = dseg_add_unique_address(cd, NULL);
3465 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_vftbl,
3469 disp = dseg_add_address(cd, super->vftbl);
3471 emit_label_beqz(cd, BRANCH_LABEL_5, s1);
3474 M_ALD(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
3475 M_ALD(REG_ITMP2, REG_PV, disp);
3477 CODEGEN_CRITICAL_SECTION_START;
3479 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3480 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3481 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3483 CODEGEN_CRITICAL_SECTION_END;
3485 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3486 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3490 emit_label(cd, BRANCH_LABEL_5);
3493 if (super == NULL) {
3494 emit_label(cd, BRANCH_LABEL_1);
3495 emit_label(cd, BRANCH_LABEL_4);
3498 emit_store_dst(jd, iptr, d);
3502 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3504 /* check for negative sizes and copy sizes to stack if necessary */
3506 MCODECHECK((iptr->s1.argcount << 1) + 64);
3508 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3510 var = VAR(iptr->sx.s23.s2.args[s1]);
3512 /* copy SAVEDVAR sizes to stack */
3514 if (!(var->flags & PREALLOC)) {
3515 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3516 #if SIZEOF_VOID_P == 8
3517 M_LST(s2, REG_SP, s1 * 8);
3519 M_IST(s2, REG_SP, (s1 + 2) * 8);
3524 /* a0 = dimension count */
3526 ICONST(REG_A0, iptr->s1.argcount);
3528 /* is patcher function set? */
3530 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3531 cr = iptr->sx.s23.s3.c.ref;
3532 disp = dseg_add_unique_address(cd, NULL);
3534 patcher_add_patch_ref(jd, PATCHER_resolve_classref_to_classinfo,
3538 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3541 /* a1 = arraydescriptor */
3543 M_ALD(REG_A1, REG_PV, disp);
3545 /* a2 = pointer to dimensions = stack pointer */
3547 #if SIZEOF_VOID_P == 8
3548 M_MOV(REG_SP, REG_A2);
3550 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3553 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3554 M_ALD(REG_ITMP3, REG_PV, disp);
3555 M_JSR(REG_RA, REG_ITMP3);
3558 /* check for exception before result assignment */
3560 emit_exception_check(cd, iptr);
3562 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3563 M_INTMOVE(REG_RESULT, d);
3564 emit_store_dst(jd, iptr, d);
3568 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3573 } /* for instruction */
3575 MCODECHECK(64); /* XXX require smaller number? */
3577 /* At the end of a basic block we may have to append some nops,
3578 because the patcher stub calling code might be longer than the
3579 actual instruction. So codepatching does not change the
3580 following block unintentionally. */
3582 if (cd->mcodeptr < cd->lastmcodeptr) {
3583 while (cd->mcodeptr < cd->lastmcodeptr)
3587 } /* if (bptr -> flags >= BBREACHED) */
3588 } /* for basic block */
3590 dseg_createlinenumbertable(cd);
3592 /* generate traps */
3594 emit_patcher_traps(jd);
3596 /* everything's ok */
3602 /* codegen_emit_stub_compiler **************************************************
3604 Emits a stub routine which calls the compiler.
3606 *******************************************************************************/
3608 void codegen_emit_stub_compiler(jitdata *jd)
3613 /* get required compiler data */
3618 /* code for the stub */
3620 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3621 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3627 /* codegen_emit_stub_native ****************************************************
3629 Emits a stub routine which calls a native method.
3631 *******************************************************************************/
3633 void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int skipparams)
3644 /* get required compiler data */
3650 /* initialize variables */
3654 /* calculate stack frame size */
3656 cd->stackframesize =
3657 1 + /* return address */
3658 sizeof(stackframeinfo_t) / SIZEOF_VOID_P +
3659 sizeof(localref_table) / SIZEOF_VOID_P +
3660 md->paramcount + /* for saving arguments over calls */
3661 #if SIZEOF_VOID_P == 4
3662 5 + /* additional save space (MIPS32) */
3664 1 + /* for saving return address */
3667 /* adjust stackframe size for 16-byte alignment */
3669 if (cd->stackframesize & 1)
3670 cd->stackframesize++;
3672 /* create method header */
3674 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3675 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3676 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3677 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3678 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3679 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3680 (void) dseg_addlinenumbertablesize(cd);
3681 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3683 /* generate stub code */
3685 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3686 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3688 #if !defined(NDEBUG)
3689 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3690 emit_verbosecall_enter(jd);
3693 /* save integer and float argument registers */
3695 #if SIZEOF_VOID_P == 8
3696 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3697 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3698 s1 = md->params[i].regoff;
3699 M_AST(s1, REG_SP, j * 8);
3704 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3705 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3706 if (!md->params[i].inmemory) {
3707 s1 = md->params[i].regoff;
3709 if (IS_2_WORD_TYPE(md->params[i].type))
3710 M_LST(s1, REG_SP, j * 8);
3712 M_IST(s1, REG_SP, j * 8);
3720 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3721 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3722 s1 = md->params[i].regoff;
3724 if (IS_2_WORD_TYPE(md->params[i].type))
3725 M_DST(s1, REG_SP, j * 8);
3727 M_FST(s1, REG_SP, j * 8);
3733 /* prepare data structures for native function call */
3735 M_MOV(REG_SP, REG_A0);
3736 M_MOV(REG_PV, REG_A1);
3737 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3738 M_ALD(REG_ITMP3, REG_PV, disp);
3739 M_JSR(REG_RA, REG_ITMP3);
3740 M_NOP; /* XXX fill me! */
3742 /* remember class argument */
3744 if (m->flags & ACC_STATIC)
3745 M_MOV(REG_RESULT, REG_ITMP3);
3747 /* restore integer and float argument registers */
3749 #if SIZEOF_VOID_P == 8
3750 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3751 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3752 s1 = md->params[i].regoff;
3753 M_LLD(s1, REG_SP, j * 8);
3758 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3759 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3760 if (!md->params[i].inmemory) {
3761 s1 = md->params[i].regoff;
3763 if (IS_2_WORD_TYPE(md->params[i].type))
3764 M_LLD(s1, REG_SP, j * 8);
3766 M_ILD(s1, REG_SP, j * 8);
3774 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3775 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3776 s1 = md->params[i].regoff;
3778 if (IS_2_WORD_TYPE(md->params[i].type))
3779 M_DLD(s1, REG_SP, j * 8);
3781 M_FLD(s1, REG_SP, j * 8);
3787 /* copy or spill arguments to new locations */
3789 for (i = md->paramcount - 1, j = i + skipparams; i >= 0; i--, j--) {
3790 t = md->params[i].type;
3792 if (IS_INT_LNG_TYPE(t)) {
3793 if (!md->params[i].inmemory) {
3794 s1 = md->params[i].regoff;
3795 s2 = nmd->params[j].regoff;
3797 if (!nmd->params[j].inmemory) {
3798 #if SIZEOF_VOID_P == 8
3801 if (IS_2_WORD_TYPE(t))
3808 #if SIZEOF_VOID_P == 8
3809 M_LST(s1, REG_SP, s2);
3811 if (IS_2_WORD_TYPE(t))
3812 M_LST(s1, REG_SP, s2);
3814 M_IST(s1, REG_SP, s2);
3819 s1 = md->params[i].regoff + cd->stackframesize * 8;
3820 s2 = nmd->params[j].regoff;
3822 #if SIZEOF_VOID_P == 8
3823 M_LLD(REG_ITMP1, REG_SP, s1);
3824 M_LST(REG_ITMP1, REG_SP, s2);
3826 if (IS_2_WORD_TYPE(t)) {
3827 M_LLD(REG_ITMP12_PACKED, REG_SP, s1);
3828 M_LST(REG_ITMP12_PACKED, REG_SP, s2);
3831 M_ILD(REG_ITMP1, REG_SP, s1);
3832 M_IST(REG_ITMP1, REG_SP, s2);
3838 if (!md->params[i].inmemory) {
3839 s1 = md->params[i].regoff;
3840 s2 = nmd->params[j].regoff;
3842 if (!nmd->params[j].inmemory) {
3843 #if SIZEOF_VOID_P == 8
3844 if (IS_2_WORD_TYPE(t))
3849 /* On MIPS32 float arguments for native functions
3850 can never be in float argument registers, since
3851 the first argument is _always_ an integer
3852 argument (JNIEnv) */
3854 if (IS_2_WORD_TYPE(t)) {
3855 /* double high/low order is endian
3856 independent: even numbered holds low
3857 32-bits, odd numbered high 32-bits */
3859 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
3860 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
3867 #if SIZEOF_VOID_P == 8
3868 if (IS_2_WORD_TYPE(t))
3869 M_DST(s1, REG_SP, s2);
3871 M_FST(s1, REG_SP, s2);
3873 /* s1 may have been originally in 2 int registers,
3874 but was moved out by the native function
3875 argument(s), just get low register */
3877 if (IS_2_WORD_TYPE(t))
3878 M_DST(GET_LOW_REG(s1), REG_SP, s2);
3880 M_FST(GET_LOW_REG(s1), REG_SP, s2);
3885 s1 = md->params[i].regoff + cd->stackframesize * 8;
3886 s2 = nmd->params[j].regoff;
3888 #if SIZEOF_VOID_P == 8
3889 if (IS_2_WORD_TYPE(t)) {
3890 M_DLD(REG_FTMP1, REG_SP, s1);
3891 M_DST(REG_FTMP1, REG_SP, s2);
3894 M_FLD(REG_FTMP1, REG_SP, s1);
3895 M_FST(REG_FTMP1, REG_SP, s2);
3898 if (IS_2_WORD_TYPE(t)) {
3899 M_DLD(REG_FTMP1, REG_SP, s1);
3900 M_DST(REG_FTMP1, REG_SP, s2);
3903 M_FLD(REG_FTMP1, REG_SP, s1);
3904 M_FST(REG_FTMP1, REG_SP, s2);
3911 /* Handle native Java methods. */
3913 if (m->flags & ACC_NATIVE) {
3914 /* put class into second argument register */
3916 if (m->flags & ACC_STATIC)
3917 M_MOV(REG_ITMP3, REG_A1);
3919 /* put env into first argument register */
3921 disp = dseg_add_address(cd, _Jv_env);
3922 M_ALD(REG_A0, REG_PV, disp);
3925 /* Call the native function. */
3927 disp = dseg_add_functionptr(cd, f);
3928 M_ALD(REG_ITMP3, REG_PV, disp); /* load adress of native method */
3929 M_JSR(REG_RA, REG_ITMP3); /* call native method */
3930 M_NOP; /* delay slot */
3932 /* save return value */
3934 switch (md->returntype.type) {
3935 #if SIZEOF_VOID_P == 8
3939 M_LST(REG_RESULT, REG_SP, 0 * 8);
3943 M_DST(REG_FRESULT, REG_SP, 0 * 8);
3948 M_IST(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3951 M_LST(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
3955 M_DST(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
3962 #if !defined(NDEBUG)
3963 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3964 emit_verbosecall_exit(jd);
3967 /* remove native stackframe info */
3969 M_MOV(REG_SP, REG_A0);
3970 M_MOV(REG_PV, REG_A1);
3971 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3972 M_ALD(REG_ITMP3, REG_PV, disp);
3973 M_JSR(REG_RA, REG_ITMP3);
3974 M_NOP; /* XXX fill me! */
3975 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3977 /* restore return value */
3979 switch (md->returntype.type) {
3980 #if SIZEOF_VOID_P == 8
3984 M_LLD(REG_RESULT, REG_SP, 0 * 8);
3988 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
3993 M_ILD(REG_RESULT, REG_SP, 2*4 + 0 * 8);
3996 M_LLD(REG_RESULT_PACKED, REG_SP, 2*4 + 0 * 8);
4000 M_DLD(REG_FRESULT, REG_SP, 2*4 + 0 * 8);
4007 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4009 /* check for exception */
4011 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4012 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4014 M_RET(REG_RA); /* return to caller */
4015 M_NOP; /* DELAY SLOT */
4017 /* handle exception */
4019 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4020 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4021 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4022 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4024 /* Generate patcher traps. */
4026 emit_patcher_traps(jd);
4031 * These are local overrides for various environment variables in Emacs.
4032 * Please do not remove this and leave it at the end of the file, where
4033 * Emacs will automagically detect them.
4034 * ---------------------------------------------------------------------
4037 * indent-tabs-mode: t
4041 * vim:noexpandtab:sw=4:ts=4: