1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
33 Contains the codegenerator for an MIPS (R4000 or higher) processor.
34 This module generates MIPS machine code for a sequence of
35 intermediate code commands (ICMDs).
37 $Id: codegen.c 7206 2007-01-11 22:39:52Z twisti $
51 #include "vm/jit/mips/arch.h"
52 #include "vm/jit/mips/codegen.h"
54 #include "native/native.h"
56 #if defined(ENABLE_THREADS)
57 # include "threads/native/lock.h"
60 #include "vm/builtin.h"
62 #include "vm/exceptions.h"
63 #include "vm/options.h"
64 #include "vm/stringlocal.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/codegen-common.h"
68 #include "vm/jit/dseg.h"
69 #include "vm/jit/emit-common.h"
70 #include "vm/jit/jit.h"
71 #include "vm/jit/patcher.h"
72 #include "vm/jit/reg.h"
73 #include "vm/jit/replace.h"
75 #if defined(ENABLE_LSRA)
76 # include "vm/jit/allocator/lsra.h"
80 /* codegen *********************************************************************
82 Generates machine code.
84 *******************************************************************************/
86 bool codegen(jitdata *jd)
92 s4 len, s1, s2, s3, d, disp;
98 constant_classref *cr;
100 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
101 unresolved_method *um;
102 builtintable_entry *bte;
105 unresolved_field *uf;
109 /* get required compiler data */
116 /* prevent compiler warnings */
129 savedregs_num = (jd->isleafmethod) ? 0 : 1; /* space to save the RA */
131 /* space to save used callee saved registers */
133 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
134 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
136 cd->stackframesize = rd->memuse + savedregs_num;
138 #if defined(ENABLE_THREADS)
139 /* space to save argument of monitor_enter */
141 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
142 # if SIZEOF_VOID_P == 8
143 cd->stackframesize++;
146 cd->stackframesize += 2;
151 /* keep stack 16-byte aligned */
153 if (cd->stackframesize & 1)
154 cd->stackframesize++;
156 /* create method header */
158 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
159 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
161 #if defined(ENABLE_THREADS)
162 /* IsSync contains the offset relative to the stack pointer for the
163 argument of monitor_exit used in the exception handler. Since the
164 offset could be zero and give a wrong meaning of the flag it is
168 if (checksync && (m->flags & ACC_SYNCHRONIZED))
169 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 8); /* IsSync */
172 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
174 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
175 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
176 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
177 dseg_addlinenumbertablesize(cd);
178 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
180 /* create exception table */
182 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
183 dseg_add_target(cd, ex->start);
184 dseg_add_target(cd, ex->end);
185 dseg_add_target(cd, ex->handler);
186 (void) dseg_add_unique_address(cd, ex->catchtype.any);
189 /* create stack frame (if necessary) */
191 if (cd->stackframesize)
192 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8);
194 /* save return address and used callee saved registers */
196 p = cd->stackframesize;
197 if (!jd->isleafmethod) {
198 p--; M_AST(REG_RA, REG_SP, p * 8);
200 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
201 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
203 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
204 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
207 /* take arguments out of register or stack frame */
211 for (p = 0, l = 0; p < md->paramcount; p++) {
212 t = md->paramtypes[p].type;
214 varindex = jd->local_map[l * 5 + t];
217 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
220 if (varindex == UNUSED)
225 s1 = md->params[p].regoff;
226 if (IS_INT_LNG_TYPE(t)) { /* integer args */
227 if (!md->params[p].inmemory) { /* register arguments */
228 #if SIZEOF_VOID_P == 8
229 s2 = rd->argintregs[s1];
230 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
231 M_INTMOVE(s2, var->vv.regoff);
232 } else { /* reg arg -> spilled */
233 M_LST(s2, REG_SP, var->vv.regoff * 8);
236 if (IS_2_WORD_TYPE(t)) {
237 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
238 rd->argintregs[GET_HIGH_REG(s1)]);
239 if (!(var->flags & INMEMORY)) /* reg arg -> register */
240 M_LNGMOVE(s2, var->vv.regoff);
241 else /* reg arg -> spilled */
242 M_LST(s2, REG_SP, var->vv.regoff * 8);
245 s2 = rd->argintregs[s1];
246 if (!(var->flags & INMEMORY)) /* reg arg -> register */
247 M_INTMOVE(s2, var->vv.regoff);
248 else /* reg arg -> spilled */
249 M_IST(s2, REG_SP, var->vv.regoff * 8);
252 } else { /* stack arguments */
253 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
254 #if SIZEOF_VOID_P == 8
255 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
257 if (IS_2_WORD_TYPE(t))
258 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
260 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
262 } else { /* stack arg -> spilled */
263 var->vv.regoff = cd->stackframesize + s1;
267 } else { /* floating args */
268 if (!md->params[p].inmemory) { /* register arguments */
269 #if SIZEOF_VOID_P == 8
270 s2 = rd->argfltregs[s1];
271 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
272 if (IS_2_WORD_TYPE(t))
273 M_DMOV(s2, var->vv.regoff);
275 M_FMOV(s2, var->vv.regoff);
276 } else { /* reg arg -> spilled */
277 if (IS_2_WORD_TYPE(t))
278 M_DST(s2, REG_SP, var->vv.regoff * 8);
280 M_FST(s2, REG_SP, var->vv.regoff * 8);
284 ((p == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
285 s2 = rd->argfltregs[s1];
286 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
287 if (IS_2_WORD_TYPE(t))
288 M_DBLMOVE(s2, var->vv.regoff);
290 M_FLTMOVE(s2, var->vv.regoff);
292 else { /* reg arg -> spilled */
293 if (IS_2_WORD_TYPE(t))
294 M_DST(s2, REG_SP, var->vv.regoff * 8);
296 M_FST(s2, REG_SP, var->vv.regoff * 8);
300 if (IS_2_WORD_TYPE(t)) {
301 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
302 rd->argintregs[GET_HIGH_REG(s1)]);
303 if (!(var->flags & INMEMORY)) {
304 M_MTC1(GET_LOW_REG(s2), var->vv.regoff);
305 M_MTC1(GET_HIGH_REG(s2), var->vv.regoff + 1);
309 M_LST(s2, REG_SP, var->vv.regoff * 8);
312 s2 = rd->argintregs[s1];
313 if (!(var->flags & INMEMORY)) {
314 M_MTC1(s2, var->vv.regoff);
318 M_IST(s2, REG_SP, var->vv.regoff * 8);
323 } else { /* stack arguments */
324 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
325 if (IS_2_WORD_TYPE(t))
326 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
328 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 8);
329 } else /* stack-arg -> spilled */
330 var->vv.regoff = cd->stackframesize + s1;
335 /* call monitorenter function */
337 #if defined(ENABLE_THREADS)
338 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
339 /* stack offset for monitor argument */
343 # if !defined(NDEBUG)
344 if (opt_verbosecall) {
345 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
347 for (p = 0; p < INT_ARG_CNT; p++)
348 M_AST(rd->argintregs[p], REG_SP, p * 8);
350 for (p = 0; p < FLT_ARG_CNT; p++)
351 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
353 s1 += INT_ARG_CNT + FLT_ARG_CNT;
357 /* get correct lock object */
359 if (m->flags & ACC_STATIC) {
360 disp = dseg_add_address(cd, &m->class->object.header);
361 M_ALD(REG_A0, REG_PV, disp);
364 /* emit_nullpointer_check(cd, iptr, REG_A0); */
369 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
370 codegen_add_nullpointerexception_ref(cd);
371 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
376 disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
377 M_ALD(REG_ITMP3, REG_PV, disp);
378 M_JSR(REG_RA, REG_ITMP3);
379 M_AST(REG_A0, REG_SP, s1 * 8); /* branch delay */
381 # if !defined(NDEBUG)
382 if (opt_verbosecall) {
383 for (p = 0; p < INT_ARG_CNT; p++)
384 M_ALD(rd->argintregs[p], REG_SP, p * 8);
386 for (p = 0; p < FLT_ARG_CNT; p++)
387 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
390 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
398 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
399 emit_verbosecall_enter(jd);
402 /* end of header generation */
404 /* create replacement points */
406 REPLACEMENT_POINTS_INIT(cd, jd);
408 /* walk through all basic blocks */
410 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
412 /* handle replacement points */
414 REPLACEMENT_POINT_BLOCK_START(cd, bptr);
416 /* store relative start of block */
418 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
420 if (bptr->flags >= BBREACHED) {
421 /* branch resolving */
423 codegen_resolve_branchrefs(cd, bptr);
425 /* copy interface registers to their destination */
429 #if defined(ENABLE_LSRA)
433 src = bptr->invars[len];
434 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
435 /* d = reg_of_var(m, src, REG_ITMP1); */
436 if (!(src->flags & INMEMORY))
440 M_INTMOVE(REG_ITMP1, d);
441 emit_store(jd, NULL, src, d);
448 var = VAR(bptr->invars[len]);
449 if ((len == bptr->indepth-1) && (bptr->type == BBTYPE_EXH)) {
450 d = codegen_reg_of_var(0, var, REG_ITMP1);
451 M_INTMOVE(REG_ITMP1, d);
452 emit_store(jd, NULL, var, d);
455 assert((var->flags & INOUT));
458 #if defined(ENABLE_LSRA)
461 /* walk through all instructions */
464 /* currentline = 0; */
466 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
467 if (iptr->line != currentline) {
468 dseg_addlinenumber(cd, iptr->line);
469 currentline = iptr->line;
472 MCODECHECK(64); /* an instruction usually needs < 64 words */
476 case ICMD_NOP: /* ... ==> ... */
477 case ICMD_POP: /* ..., value ==> ... */
478 case ICMD_POP2: /* ..., value, value ==> ... */
481 case ICMD_INLINE_START:
483 REPLACEMENT_POINT_INLINE_START(cd, iptr);
486 case ICMD_INLINE_BODY:
488 REPLACEMENT_POINT_INLINE_BODY(cd, iptr);
489 dseg_addlinenumber_inline_start(cd, iptr);
490 dseg_addlinenumber(cd, iptr->line);
493 case ICMD_INLINE_END:
495 dseg_addlinenumber_inline_end(cd, iptr);
496 dseg_addlinenumber(cd, iptr->line);
499 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
501 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
502 emit_nullpointer_check(cd, iptr, s1);
505 /* constant operations ************************************************/
507 case ICMD_ICONST: /* ... ==> ..., constant */
509 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
510 ICONST(d, iptr->sx.val.i);
511 emit_store_dst(jd, iptr, d);
514 case ICMD_LCONST: /* ... ==> ..., constant */
516 #if SIZEOF_VOID_P == 8
517 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
519 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
521 LCONST(d, iptr->sx.val.l);
522 emit_store_dst(jd, iptr, d);
525 case ICMD_FCONST: /* ... ==> ..., constant */
527 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
528 disp = dseg_add_float(cd, iptr->sx.val.f);
529 M_FLD(d, REG_PV, disp);
530 emit_store_dst(jd, iptr, d);
533 case ICMD_DCONST: /* ... ==> ..., constant */
535 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
536 disp = dseg_add_double(cd, iptr->sx.val.d);
537 M_DLD(d, REG_PV, disp);
538 emit_store_dst(jd, iptr, d);
541 case ICMD_ACONST: /* ... ==> ..., constant */
543 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
545 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
546 cr = iptr->sx.val.c.ref;
547 disp = dseg_add_unique_address(cd, cr);
549 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
551 M_ALD(d, REG_PV, disp);
554 if (iptr->sx.val.anyptr == NULL)
555 M_INTMOVE(REG_ZERO, d);
557 disp = dseg_add_address(cd, iptr->sx.val.anyptr);
558 M_ALD(d, REG_PV, disp);
561 emit_store_dst(jd, iptr, d);
565 /* load/store/copy/move operations ************************************/
567 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
568 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
569 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
570 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
571 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
572 case ICMD_ISTORE: /* ..., value ==> ... */
573 case ICMD_LSTORE: /* ..., value ==> ... */
574 case ICMD_FSTORE: /* ..., value ==> ... */
575 case ICMD_DSTORE: /* ..., value ==> ... */
579 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
583 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
584 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
588 /* integer operations *************************************************/
590 case ICMD_INEG: /* ..., value ==> ..., - value */
592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
594 M_ISUB(REG_ZERO, s1, d);
595 emit_store_dst(jd, iptr, d);
598 case ICMD_LNEG: /* ..., value ==> ..., - value */
600 #if SIZEOF_VOID_P == 8
601 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
602 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
603 M_LSUB(REG_ZERO, s1, d);
605 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
607 M_ISUB(REG_ZERO, GET_LOW_REG(s1), GET_LOW_REG(d));
608 M_ISUB(REG_ZERO, GET_HIGH_REG(s1), GET_HIGH_REG(d));
609 M_CMPULT(REG_ZERO, GET_LOW_REG(d), REG_ITMP3);
610 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
612 emit_store_dst(jd, iptr, d);
615 case ICMD_I2L: /* ..., value ==> ..., value */
617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
618 #if SIZEOF_VOID_P == 8
619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
622 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
623 M_INTMOVE(s1, GET_LOW_REG(d));
624 M_ISRA_IMM(GET_LOW_REG(d), 31, GET_HIGH_REG(d));
626 emit_store_dst(jd, iptr, d);
629 case ICMD_L2I: /* ..., value ==> ..., value */
631 #if SIZEOF_VOID_P == 8
632 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
633 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
634 M_ISLL_IMM(s1, 0, d);
636 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
638 M_INTMOVE(GET_LOW_REG(s1), d);
640 emit_store_dst(jd, iptr, d);
643 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
645 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
646 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
647 #if SIZEOF_VOID_P == 8
648 M_LSLL_IMM(s1, 56, d);
649 M_LSRA_IMM( d, 56, d);
651 M_ISLL_IMM(s1, 24, d);
652 M_ISRA_IMM( d, 24, d);
654 emit_store_dst(jd, iptr, d);
657 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
659 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
661 M_AND_IMM(s1, 0xffff, d);
662 emit_store_dst(jd, iptr, d);
665 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
667 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
668 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
669 #if SIZEOF_VOID_P == 8
670 M_LSLL_IMM(s1, 48, d);
671 M_LSRA_IMM( d, 48, d);
673 M_ISLL_IMM(s1, 16, d);
674 M_ISRA_IMM( d, 16, d);
676 emit_store_dst(jd, iptr, d);
680 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
682 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
683 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
686 emit_store_dst(jd, iptr, d);
690 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
691 /* sx.val.i = constant */
693 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
694 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
695 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
696 M_IADD_IMM(s1, iptr->sx.val.i, d);
698 ICONST(REG_ITMP2, iptr->sx.val.i);
699 M_IADD(s1, REG_ITMP2, d);
701 emit_store_dst(jd, iptr, d);
704 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
706 #if SIZEOF_VOID_P == 8
707 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
708 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
709 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
712 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
713 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
715 M_IADD(s1, s2, GET_HIGH_REG(d));
716 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
717 s2 = emit_load_s2_low(jd, iptr, GET_LOW_REG(REG_ITMP12_PACKED));
718 if (s1 == GET_LOW_REG(d)) {
719 M_MOV(s1, REG_ITMP3);
722 M_IADD(s1, s2, GET_LOW_REG(d));
723 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
724 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
726 emit_store_dst(jd, iptr, d);
729 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
730 /* sx.val.l = constant */
732 #if SIZEOF_VOID_P == 8
733 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
734 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
735 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767))
736 M_LADD_IMM(s1, iptr->sx.val.l, d);
738 LCONST(REG_ITMP2, iptr->sx.val.l);
739 M_LADD(s1, REG_ITMP2, d);
742 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
743 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32767)) {
744 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
745 M_IADD_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
746 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
747 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
749 else if ((iptr->sx.val.l >= (-32768 + 1)) && (iptr->sx.val.l < 0)) {
750 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
751 M_ISUB_IMM(s1, -(iptr->sx.val.l), GET_LOW_REG(d));
752 M_CMPULT_IMM(GET_LOW_REG(d), iptr->sx.val.l, REG_ITMP3);
753 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
754 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
755 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
758 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
759 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
760 M_IADD(s1, REG_ITMP2, GET_LOW_REG(d));
761 M_CMPULT(GET_LOW_REG(d), s1, REG_ITMP3);
762 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
763 M_IADD(s1, REG_ITMP3, GET_HIGH_REG(d));
764 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
765 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
768 emit_store_dst(jd, iptr, d);
771 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
773 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
774 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
775 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
777 emit_store_dst(jd, iptr, d);
780 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
781 /* sx.val.i = constant */
783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
784 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
785 if ((iptr->sx.val.i >= -32767) && (iptr->sx.val.i <= 32768))
786 M_IADD_IMM(s1, -iptr->sx.val.i, d);
788 ICONST(REG_ITMP2, iptr->sx.val.i);
789 M_ISUB(s1, REG_ITMP2, d);
791 emit_store_dst(jd, iptr, d);
794 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
796 #if SIZEOF_VOID_P == 8
797 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
798 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
799 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
802 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
803 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
804 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
805 M_ISUB(s1, s2, GET_HIGH_REG(d));
806 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
807 s2 = emit_load_s2_low(jd, iptr, REG_ITMP1);
808 M_CMPULT(s1, s2, REG_ITMP3);
809 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
810 /* if s1 is equal to REG_ITMP3 we have to reload it, since
811 the CMPULT instruction destroyed it */
813 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
814 M_ISUB(s1, s2, GET_LOW_REG(d));
817 emit_store_dst(jd, iptr, d);
820 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
821 /* sx.val.l = constant */
823 #if SIZEOF_VOID_P == 8
824 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
826 if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l <= 32768))
827 M_LADD_IMM(s1, -iptr->sx.val.l, d);
829 LCONST(REG_ITMP2, iptr->sx.val.l);
830 M_LSUB(s1, REG_ITMP2, d);
833 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
834 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 32768)) {
835 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
836 M_ISUB_IMM(s1, iptr->sx.val.l, GET_LOW_REG(d));
837 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
838 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
839 M_ISUB_IMM(s1, 1, GET_HIGH_REG(d));
840 M_IADD(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
842 else if ((iptr->sx.val.l >= -32767) && (iptr->sx.val.l < 0)) {
843 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
844 M_IADD_IMM(GET_LOW_REG(s1), -(iptr->sx.val.l), GET_LOW_REG(d));
845 M_CMPULT_IMM(GET_LOW_REG(d), -(iptr->sx.val.l), REG_ITMP3);
846 M_IADD(GET_HIGH_REG(s1), REG_ITMP3, GET_HIGH_REG(d));
849 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
850 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
851 M_ISUB(s1, REG_ITMP2, GET_LOW_REG(d));
852 M_CMPULT(s1, REG_ITMP2, REG_ITMP3);
853 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
854 M_ISUB(s1, REG_ITMP3, GET_HIGH_REG(d));
855 ICONST(REG_ITMP3, iptr->sx.val.l >> 32);
856 M_ISUB(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
859 emit_store_dst(jd, iptr, d);
862 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
864 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
865 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
866 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
871 emit_store_dst(jd, iptr, d);
874 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
875 /* sx.val.i = constant */
877 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
878 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
879 ICONST(REG_ITMP2, iptr->sx.val.i);
880 M_IMUL(s1, REG_ITMP2);
884 emit_store_dst(jd, iptr, d);
887 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
889 #if SIZEOF_VOID_P == 8
890 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
891 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
892 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
898 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
899 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
900 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
905 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
907 M_MFHI(GET_HIGH_REG(d));
908 M_MFLO(GET_LOW_REG(d));
911 M_IADD(GET_HIGH_REG(d), REG_ITMP3, REG_ITMP3);
913 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
914 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
917 /* XXX do we need nops here? */
919 emit_store_dst(jd, iptr, d);
922 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
923 /* sx.val.l = constant */
925 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
926 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
927 LCONST(REG_ITMP2, iptr->sx.val.l);
928 M_LMUL(s1, REG_ITMP2);
932 emit_store_dst(jd, iptr, d);
935 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
937 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
938 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
939 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
940 emit_arithmetic_check(cd, iptr, s2);
945 emit_store_dst(jd, iptr, d);
948 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
950 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
951 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
952 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
953 emit_arithmetic_check(cd, iptr, s2);
958 emit_store_dst(jd, iptr, d);
961 #if SIZEOF_VOID_P == 8
963 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
965 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
966 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
968 emit_arithmetic_check(cd, iptr, s2);
973 emit_store_dst(jd, iptr, d);
976 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
978 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
979 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
980 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
981 emit_arithmetic_check(cd, iptr, s2);
986 emit_store_dst(jd, iptr, d);
989 #else /* SIZEOF_VOID_P == 8 */
991 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
992 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
994 bte = iptr->sx.s23.s3.bte;
997 s2 = emit_load_s2(jd, iptr, REG_ITMP12_PACKED);
998 M_OR(GET_HIGH_REG(s2), GET_LOW_REG(s2), REG_ITMP3);
999 emit_arithmetic_check(cd, iptr, REG_ITMP3);
1001 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[1].regoff)],
1002 rd->argintregs[GET_HIGH_REG(md->params[1].regoff)]);
1005 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1006 s3 = PACK_REGS(rd->argintregs[GET_LOW_REG(md->params[0].regoff)],
1007 rd->argintregs[GET_HIGH_REG(md->params[0].regoff)]);
1010 disp = dseg_add_functionptr(cd, bte->fp);
1011 M_ALD(REG_ITMP3, REG_PV, disp);
1012 M_JSR(REG_RA, REG_ITMP3);
1015 d = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
1016 M_LNGMOVE(REG_RESULT_PACKED, d);
1017 emit_store_dst(jd, iptr, d);
1020 #endif /* SIZEOF_VOID_P == 8 */
1022 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1023 /* val.i = constant */
1025 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1026 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1027 #if SIZEOF_VOID_P == 8
1028 M_LSRA_IMM(s1, 63, REG_ITMP2);
1029 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1030 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1031 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1033 M_ISRA_IMM(s1, 31, REG_ITMP2);
1034 M_ISRL_IMM(REG_ITMP2, 32 - iptr->sx.val.i, REG_ITMP2);
1035 M_IADD(s1, REG_ITMP2, REG_ITMP2);
1036 M_ISRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1038 emit_store_dst(jd, iptr, d);
1041 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1042 /* val.i = constant */
1044 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1045 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1047 M_MOV(s1, REG_ITMP1);
1050 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff)) {
1051 M_AND_IMM(s1, iptr->sx.val.i, d);
1054 M_ISUB(REG_ZERO, s1, d);
1055 M_AND_IMM(d, iptr->sx.val.i, d);
1058 ICONST(REG_ITMP2, iptr->sx.val.i);
1059 M_AND(s1, REG_ITMP2, d);
1062 M_ISUB(REG_ZERO, s1, d);
1063 M_AND(d, REG_ITMP2, d);
1065 M_ISUB(REG_ZERO, d, d);
1066 emit_store_dst(jd, iptr, d);
1069 #if SIZEOF_VOID_P == 8
1071 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
1072 /* val.i = constant */
1074 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1075 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1076 M_LSRA_IMM(s1, 63, REG_ITMP2);
1077 M_LSRL_IMM(REG_ITMP2, 64 - iptr->sx.val.i, REG_ITMP2);
1078 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1079 M_LSRA_IMM(REG_ITMP2, iptr->sx.val.i, d);
1080 emit_store_dst(jd, iptr, d);
1083 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1084 /* val.l = constant */
1086 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1087 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1089 M_MOV(s1, REG_ITMP1);
1092 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1093 M_AND_IMM(s1, iptr->sx.val.l, d);
1096 M_LSUB(REG_ZERO, s1, d);
1097 M_AND_IMM(d, iptr->sx.val.l, d);
1100 LCONST(REG_ITMP2, iptr->sx.val.l);
1101 M_AND(s1, REG_ITMP2, d);
1104 M_LSUB(REG_ZERO, s1, d);
1105 M_AND(d, REG_ITMP2, d);
1107 M_LSUB(REG_ZERO, d, d);
1108 emit_store_dst(jd, iptr, d);
1111 #endif /* SIZEOF_VOID_P == 8 */
1113 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1117 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1119 emit_store_dst(jd, iptr, d);
1122 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1123 /* sx.val.i = constant */
1125 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1126 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1127 M_ISLL_IMM(s1, iptr->sx.val.i, d);
1128 emit_store_dst(jd, iptr, d);
1131 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1133 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1134 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1135 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1137 emit_store_dst(jd, iptr, d);
1140 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1141 /* sx.val.i = constant */
1143 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1144 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1145 M_ISRA_IMM(s1, iptr->sx.val.i, d);
1146 emit_store_dst(jd, iptr, d);
1149 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1151 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1152 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1155 emit_store_dst(jd, iptr, d);
1158 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1159 /* sx.val.i = constant */
1161 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1162 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1163 M_ISRL_IMM(s1, iptr->sx.val.i, d);
1164 emit_store_dst(jd, iptr, d);
1167 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1169 #if SIZEOF_VOID_P == 8
1170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1171 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1172 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1175 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1176 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1177 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1179 M_ISLL(s2, 26, REG_ITMP1);
1180 M_BGEZ(REG_ITMP1, 3);
1183 M_ISLL(GET_LOW_REG(s1), s2, GET_HIGH_REG(d));
1185 M_MOV(REG_ZERO, GET_LOW_REG(d)); /* delay slot */
1188 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1190 M_BEQZ(REG_ITMP1, 4);
1191 M_ISLL(GET_HIGH_REG(s1), s2, GET_HIGH_REG(d)); /* delay slot */
1193 M_ISUB(s2, REG_ZERO, REG_ITMP3);
1194 M_ISRL(GET_LOW_REG(s1), REG_ITMP3, REG_ITMP3);
1195 M_OR(GET_HIGH_REG(d), REG_ITMP3, GET_HIGH_REG(d));
1198 M_ISLL(GET_LOW_REG(s1), s2, GET_LOW_REG(d));
1201 emit_store_dst(jd, iptr, d);
1204 #if SIZEOF_VOID_P == 8
1206 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1207 /* sx.val.i = constant */
1209 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1210 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1211 M_LSLL_IMM(s1, iptr->sx.val.i, d);
1212 emit_store_dst(jd, iptr, d);
1215 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1217 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1218 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1219 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1221 emit_store_dst(jd, iptr, d);
1224 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1225 /* sx.val.i = constant */
1227 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1228 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1229 M_LSRA_IMM(s1, iptr->sx.val.i, d);
1230 emit_store_dst(jd, iptr, d);
1233 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1235 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1236 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1237 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1239 emit_store_dst(jd, iptr, d);
1242 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1243 /* sx.val.i = constant */
1245 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1246 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1247 M_LSRL_IMM(s1, iptr->sx.val.i, d);
1248 emit_store_dst(jd, iptr, d);
1251 #endif /* SIZEOF_VOID_P == 8 */
1253 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1255 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1256 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1257 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1259 emit_store_dst(jd, iptr, d);
1262 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1263 /* sx.val.i = constant */
1265 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1266 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1267 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1268 M_AND_IMM(s1, iptr->sx.val.i, d);
1270 ICONST(REG_ITMP2, iptr->sx.val.i);
1271 M_AND(s1, REG_ITMP2, d);
1273 emit_store_dst(jd, iptr, d);
1276 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1278 #if SIZEOF_VOID_P == 8
1279 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1280 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1281 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1284 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1285 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1286 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1287 M_AND(s1, s2, GET_LOW_REG(d));
1288 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1289 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1290 M_AND(s1, s2, GET_HIGH_REG(d));
1292 emit_store_dst(jd, iptr, d);
1295 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1296 /* sx.val.l = constant */
1298 #if SIZEOF_VOID_P == 8
1299 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1300 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1301 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1302 M_AND_IMM(s1, iptr->sx.val.l, d);
1304 LCONST(REG_ITMP2, iptr->sx.val.l);
1305 M_AND(s1, REG_ITMP2, d);
1308 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1309 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1310 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1311 M_AND_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1312 M_AND_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1315 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1316 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1317 M_AND(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1318 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1319 M_AND(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1322 emit_store_dst(jd, iptr, d);
1325 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1328 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1329 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1331 emit_store_dst(jd, iptr, d);
1334 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1335 /* sx.val.i = constant */
1337 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1338 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1339 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1340 M_OR_IMM(s1, iptr->sx.val.i, d);
1342 ICONST(REG_ITMP2, iptr->sx.val.i);
1343 M_OR(s1, REG_ITMP2, d);
1345 emit_store_dst(jd, iptr, d);
1348 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1350 #if SIZEOF_VOID_P == 8
1351 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1352 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1353 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1356 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1357 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1358 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1359 M_OR(s1, s2, GET_LOW_REG(d));
1360 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1361 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1362 M_OR(s1, s2, GET_HIGH_REG(d));
1364 emit_store_dst(jd, iptr, d);
1367 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1368 /* sx.val.l = constant */
1370 #if SIZEOF_VOID_P == 8
1371 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1372 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1373 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1374 M_OR_IMM(s1, iptr->sx.val.l, d);
1376 LCONST(REG_ITMP2, iptr->sx.val.l);
1377 M_OR(s1, REG_ITMP2, d);
1380 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1381 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1382 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1383 M_OR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1384 M_OR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1387 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1388 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1389 M_OR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1390 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1391 M_OR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1394 emit_store_dst(jd, iptr, d);
1397 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1399 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1400 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1401 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1403 emit_store_dst(jd, iptr, d);
1406 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1407 /* sx.val.i = constant */
1409 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1410 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1411 if ((iptr->sx.val.i >= 0) && (iptr->sx.val.i <= 0xffff))
1412 M_XOR_IMM(s1, iptr->sx.val.i, d);
1414 ICONST(REG_ITMP2, iptr->sx.val.i);
1415 M_XOR(s1, REG_ITMP2, d);
1417 emit_store_dst(jd, iptr, d);
1420 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1422 #if SIZEOF_VOID_P == 8
1423 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1424 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1425 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1428 s1 = emit_load_s1_low(jd, iptr, REG_ITMP2);
1429 s2 = emit_load_s2_low(jd, iptr, REG_ITMP3);
1430 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1431 M_XOR(s1, s2, GET_LOW_REG(d));
1432 s1 = emit_load_s1_high(jd, iptr, REG_ITMP2);
1433 s2 = emit_load_s2_high(jd, iptr, REG_ITMP3);
1434 M_XOR(s1, s2, GET_HIGH_REG(d));
1436 emit_store_dst(jd, iptr, d);
1439 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1440 /* sx.val.l = constant */
1442 #if SIZEOF_VOID_P == 8
1443 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1444 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1445 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff))
1446 M_XOR_IMM(s1, iptr->sx.val.l, d);
1448 LCONST(REG_ITMP2, iptr->sx.val.l);
1449 M_XOR(s1, REG_ITMP2, d);
1452 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1453 if ((iptr->sx.val.l >= 0) && (iptr->sx.val.l <= 0xffff)) {
1454 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
1455 M_XOR_IMM(GET_LOW_REG(s1), iptr->sx.val.l, GET_LOW_REG(d));
1456 M_XOR_IMM(GET_HIGH_REG(s1), 0, GET_HIGH_REG(d));
1459 LCONST(REG_ITMP12_PACKED, iptr->sx.val.l);
1460 s1 = emit_load_s1_low(jd, iptr, REG_ITMP3);
1461 M_XOR(s1, GET_LOW_REG(REG_ITMP12_PACKED), GET_LOW_REG(d));
1462 s1 = emit_load_s1_high(jd, iptr, REG_ITMP3);
1463 M_XOR(s1, GET_HIGH_REG(REG_ITMP12_PACKED), GET_HIGH_REG(d));
1466 emit_store_dst(jd, iptr, d);
1470 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1472 #if SIZEOF_VOID_P == 8
1473 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1474 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1475 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1476 M_CMPLT(s1, s2, REG_ITMP3);
1477 M_CMPLT(s2, s1, REG_ITMP1);
1478 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1480 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
1481 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
1482 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1483 M_CMPLT(s1, s2, REG_ITMP3);
1484 M_CMPLT(s2, s1, REG_ITMP1);
1485 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1488 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
1489 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
1490 M_CMPULT(s1, s2, REG_ITMP3);
1491 M_CMPULT(s2, s1, REG_ITMP1);
1492 M_ISUB(REG_ITMP1, REG_ITMP3, d);
1494 emit_store_dst(jd, iptr, d);
1498 /* floating operations ************************************************/
1500 case ICMD_FNEG: /* ..., value ==> ..., - value */
1502 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1503 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1505 emit_store_dst(jd, iptr, d);
1508 case ICMD_DNEG: /* ..., value ==> ..., - value */
1510 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1511 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1513 emit_store_dst(jd, iptr, d);
1516 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1518 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1519 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1520 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1522 emit_store_dst(jd, iptr, d);
1525 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1527 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1528 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1529 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1531 emit_store_dst(jd, iptr, d);
1534 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1536 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1537 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1538 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1540 emit_store_dst(jd, iptr, d);
1543 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1545 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1546 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1547 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1549 emit_store_dst(jd, iptr, d);
1552 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1554 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1555 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1556 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1558 emit_store_dst(jd, iptr, d);
1561 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1563 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1564 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1565 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1567 emit_store_dst(jd, iptr, d);
1570 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1572 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1573 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1574 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1576 emit_store_dst(jd, iptr, d);
1579 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1581 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1582 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1583 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1585 emit_store_dst(jd, iptr, d);
1589 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1591 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1592 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1593 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1594 M_FDIV(s1,s2, REG_FTMP3);
1595 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1596 M_CVTLF(REG_FTMP3, REG_FTMP3);
1597 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1598 M_FSUB(s1, REG_FTMP3, d);
1599 emit_store_dst(jd, iptr, d);
1602 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1604 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1605 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1606 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1607 M_DDIV(s1,s2, REG_FTMP3);
1608 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1609 M_CVTLD(REG_FTMP3, REG_FTMP3);
1610 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1611 M_DSUB(s1, REG_FTMP3, d);
1612 emit_store_dst(jd, iptr, d);
1616 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1618 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1619 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1622 emit_store_dst(jd, iptr, d);
1625 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1627 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1628 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1631 emit_store_dst(jd, iptr, d);
1635 /* XXX these do not work correctly */
1637 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1639 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1640 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1641 M_TRUNCFI(s1, REG_FTMP1);
1642 M_MOVDI(REG_FTMP1, d);
1644 emit_store_dst(jd, iptr, d);
1647 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1649 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1650 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1651 M_TRUNCDI(s1, REG_FTMP1);
1652 M_MOVDI(REG_FTMP1, d);
1654 emit_store_dst(jd, iptr, d);
1657 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1659 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1661 M_TRUNCFL(s1, REG_FTMP1);
1662 M_MOVDL(REG_FTMP1, d);
1664 emit_store_dst(jd, iptr, d);
1667 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1669 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1670 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1671 M_TRUNCDL(s1, REG_FTMP1);
1672 M_MOVDL(REG_FTMP1, d);
1674 emit_store_dst(jd, iptr, d);
1678 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1680 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1681 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1683 emit_store_dst(jd, iptr, d);
1686 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1688 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1689 d = codegen_reg_of_dst(jd, iptr, REG_FTMP2);
1691 emit_store_dst(jd, iptr, d);
1694 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1696 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1697 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1698 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1701 M_AADD_IMM(REG_ZERO, 1, d);
1705 M_ASUB_IMM(REG_ZERO, 1, d);
1706 M_CMOVT(REG_ZERO, d);
1707 emit_store_dst(jd, iptr, d);
1710 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1712 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1713 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1714 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1717 M_AADD_IMM(REG_ZERO, 1, d);
1721 M_ASUB_IMM(REG_ZERO, 1, d);
1722 M_CMOVT(REG_ZERO, d);
1723 emit_store_dst(jd, iptr, d);
1726 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1728 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1729 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1730 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1733 M_ASUB_IMM(REG_ZERO, 1, d);
1737 M_AADD_IMM(REG_ZERO, 1, d);
1738 M_CMOVT(REG_ZERO, d);
1739 emit_store_dst(jd, iptr, d);
1742 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1744 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1745 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1749 M_ASUB_IMM(REG_ZERO, 1, d);
1753 M_AADD_IMM(REG_ZERO, 1, d);
1754 M_CMOVT(REG_ZERO, d);
1755 emit_store_dst(jd, iptr, d);
1759 /* memory operations **************************************************/
1761 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1763 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1764 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1765 emit_nullpointer_check(cd, iptr, s1);
1766 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1767 emit_store_dst(jd, iptr, d);
1770 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1772 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1773 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1774 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1775 emit_array_checks(cd, iptr, s1, s2);
1776 M_AADD(s2, s1, REG_ITMP3);
1777 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1778 emit_store_dst(jd, iptr, d);
1781 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1783 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1784 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1785 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1786 emit_array_checks(cd, iptr, s1, s2);
1787 M_AADD(s2, s1, REG_ITMP3);
1788 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1789 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1790 emit_store_dst(jd, iptr, d);
1793 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1795 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1796 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1797 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1798 emit_array_checks(cd, iptr, s1, s2);
1799 M_AADD(s2, s1, REG_ITMP3);
1800 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1801 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1802 emit_store_dst(jd, iptr, d);
1805 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1807 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1808 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1809 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1810 emit_array_checks(cd, iptr, s1, s2);
1811 M_ASLL_IMM(s2, 2, REG_ITMP3);
1812 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1813 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1814 emit_store_dst(jd, iptr, d);
1817 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1819 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1820 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1821 #if SIZEOF_VOID_P == 8
1822 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1824 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
1826 emit_array_checks(cd, iptr, s1, s2);
1827 M_ASLL_IMM(s2, 3, REG_ITMP3);
1828 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1829 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1830 emit_store_dst(jd, iptr, d);
1833 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1835 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1836 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1837 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1838 emit_array_checks(cd, iptr, s1, s2);
1839 M_ASLL_IMM(s2, 2, REG_ITMP3);
1840 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1841 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1842 emit_store_dst(jd, iptr, d);
1845 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1849 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1850 emit_array_checks(cd, iptr, s1, s2);
1851 M_ASLL_IMM(s2, 3, REG_ITMP3);
1852 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1853 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1854 emit_store_dst(jd, iptr, d);
1857 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1859 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1860 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1861 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1862 emit_array_checks(cd, iptr, s1, s2);
1863 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1864 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1865 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1866 emit_store_dst(jd, iptr, d);
1870 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1872 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1873 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1874 emit_array_checks(cd, iptr, s1, s2);
1875 M_AADD(s2, s1, REG_ITMP1);
1876 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1877 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1880 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1881 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1884 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1885 emit_array_checks(cd, iptr, s1, s2);
1886 M_AADD(s2, s1, REG_ITMP1);
1887 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1888 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1889 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1892 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1894 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1895 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1896 emit_array_checks(cd, iptr, s1, s2);
1897 M_ASLL_IMM(s2, 2, REG_ITMP2);
1898 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1899 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1900 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1903 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1905 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1906 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1907 emit_array_checks(cd, iptr, s1, s2);
1908 M_ASLL_IMM(s2, 3, REG_ITMP2);
1909 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1910 #if SIZEOF_VOID_P == 8
1911 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1913 s3 = emit_load_s3(jd, iptr, REG_ITMP23_PACKED);
1915 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1918 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1921 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1922 emit_array_checks(cd, iptr, s1, s2);
1923 M_ASLL_IMM(s2, 2, REG_ITMP2);
1924 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1925 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1926 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1929 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1931 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1932 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1933 emit_array_checks(cd, iptr, s1, s2);
1934 M_ASLL_IMM(s2, 3, REG_ITMP2);
1935 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1936 s3 = emit_load_s3(jd, iptr, REG_FTMP1);
1937 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1941 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1943 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1944 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1945 emit_array_checks(cd, iptr, s1, s2);
1946 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1950 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1951 M_ALD(REG_ITMP3, REG_PV, disp);
1952 M_JSR(REG_RA, REG_ITMP3);
1955 /* M_BEQZ(REG_RESULT, 0); */
1956 /* codegen_add_arraystoreexception_ref(cd); */
1958 emit_arraystore_check(cd, iptr, REG_RESULT);
1960 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1961 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1962 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1963 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1964 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1965 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1969 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1971 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1972 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1973 emit_array_checks(cd, iptr, s1, s2);
1974 M_AADD(s2, s1, REG_ITMP1);
1975 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1978 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1979 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1981 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1982 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1983 emit_array_checks(cd, iptr, s1, s2);
1984 M_AADD(s2, s1, REG_ITMP1);
1985 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1986 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1989 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1991 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1992 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1993 emit_array_checks(cd, iptr, s1, s2);
1994 M_ASLL_IMM(s2, 2, REG_ITMP2);
1995 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1996 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1999 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2001 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2002 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2003 emit_array_checks(cd, iptr, s1, s2);
2004 M_ASLL_IMM(s2, 3, REG_ITMP2);
2005 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2006 #if SIZEOF_VOID_P == 8
2007 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
2009 M_LST_INTERN(PACK_REGS(REG_ZERO, REG_ZERO), REG_ITMP1, OFFSET(java_longarray, data[0]));
2013 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2015 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2016 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2017 emit_array_checks(cd, iptr, s1, s2);
2018 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
2019 M_AADD(REG_ITMP2, s1, REG_ITMP1);
2020 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
2024 case ICMD_GETSTATIC: /* ... ==> ..., value */
2026 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2027 uf = iptr->sx.s23.s3.uf;
2028 fieldtype = uf->fieldref->parseddesc.fd->type;
2029 disp = dseg_add_unique_address(cd, uf);
2031 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2034 fi = iptr->sx.s23.s3.fmiref->p.field;
2035 fieldtype = fi->type;
2036 disp = dseg_add_address(cd, &(fi->value));
2038 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2039 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2042 M_ALD(REG_ITMP1, REG_PV, disp);
2044 switch (fieldtype) {
2046 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2047 M_ILD_INTERN(d, REG_ITMP1, 0);
2050 #if SIZEOF_VOID_P == 8
2051 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2053 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2055 M_LLD_INTERN(d, REG_ITMP1, 0);
2058 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2059 M_ALD_INTERN(d, REG_ITMP1, 0);
2062 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2063 M_FLD_INTERN(d, REG_ITMP1, 0);
2066 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2067 M_DLD_INTERN(d, REG_ITMP1, 0);
2070 emit_store_dst(jd, iptr, d);
2073 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2075 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2076 uf = iptr->sx.s23.s3.uf;
2077 fieldtype = uf->fieldref->parseddesc.fd->type;
2078 disp = dseg_add_unique_address(cd, uf);
2080 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2083 fi = iptr->sx.s23.s3.fmiref->p.field;
2084 fieldtype = fi->type;
2085 disp = dseg_add_address(cd, &(fi->value));
2087 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2088 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2091 M_ALD(REG_ITMP1, REG_PV, disp);
2093 switch (fieldtype) {
2095 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2096 M_IST_INTERN(s1, REG_ITMP1, 0);
2099 #if SIZEOF_VOID_P == 8
2100 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2102 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2104 M_LST_INTERN(s1, REG_ITMP1, 0);
2107 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2108 M_AST_INTERN(s1, REG_ITMP1, 0);
2111 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2112 M_FST_INTERN(s1, REG_ITMP1, 0);
2115 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2116 M_DST_INTERN(s1, REG_ITMP1, 0);
2121 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2122 /* val = value (in current instruction) */
2123 /* following NOP) */
2125 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2126 uf = iptr->sx.s23.s3.uf;
2127 fieldtype = uf->fieldref->parseddesc.fd->type;
2128 disp = dseg_add_unique_address(cd, uf);
2130 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2133 fi = iptr->sx.s23.s3.fmiref->p.field;
2134 fieldtype = fi->type;
2135 disp = dseg_add_address(cd, &(fi->value));
2137 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2138 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, disp);
2141 M_ALD(REG_ITMP1, REG_PV, disp);
2143 switch (fieldtype) {
2145 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2148 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2151 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2154 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2157 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2163 case ICMD_GETFIELD: /* ... ==> ..., value */
2165 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2166 emit_nullpointer_check(cd, iptr, s1);
2168 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2169 uf = iptr->sx.s23.s3.uf;
2170 fieldtype = uf->fieldref->parseddesc.fd->type;
2173 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2176 fi = iptr->sx.s23.s3.fmiref->p.field;
2177 fieldtype = fi->type;
2181 switch (fieldtype) {
2183 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2187 #if SIZEOF_VOID_P == 8
2188 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2191 d = codegen_reg_of_dst(jd, iptr, REG_ITMP23_PACKED);
2192 M_LLD_GETFIELD(d, s1, disp);
2196 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2200 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2204 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2208 emit_store_dst(jd, iptr, d);
2211 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2213 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2214 emit_nullpointer_check(cd, iptr, s1);
2216 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2217 uf = iptr->sx.s23.s3.uf;
2218 fieldtype = uf->fieldref->parseddesc.fd->type;
2222 fi = iptr->sx.s23.s3.fmiref->p.field;
2223 fieldtype = fi->type;
2227 #if SIZEOF_VOID_P == 8
2228 if (IS_INT_LNG_TYPE(fieldtype))
2229 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2231 s2 = emit_load_s2(jd, iptr, REG_FTMP1);
2233 if (IS_INT_LNG_TYPE(fieldtype)) {
2234 if (IS_2_WORD_TYPE(fieldtype))
2235 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2237 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2240 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2243 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2244 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2246 switch (fieldtype) {
2248 M_IST(s2, s1, disp);
2251 M_LST(s2, s1, disp);
2254 M_AST(s2, s1, disp);
2257 M_FST(s2, s1, disp);
2260 M_DST(s2, s1, disp);
2265 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2267 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2268 emit_nullpointer_check(cd, iptr, s1);
2270 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2271 unresolved_field *uf = iptr->sx.s23.s3.uf;
2273 fieldtype = uf->fieldref->parseddesc.fd->type;
2276 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2279 fieldinfo *fi = iptr->sx.s23.s3.fmiref->p.field;
2280 fieldtype = fi->type;
2284 switch (fieldtype) {
2286 M_IST(REG_ZERO, s1, disp);
2289 M_LST(REG_ZERO, s1, disp);
2292 M_AST(REG_ZERO, s1, disp);
2295 M_FST(REG_ZERO, s1, disp);
2298 M_DST(REG_ZERO, s1, disp);
2304 /* branch operations **************************************************/
2306 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2309 M_INTMOVE(s1, REG_ITMP1_XPTR);
2311 #ifdef ENABLE_VERIFIER
2312 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2313 uc = iptr->sx.s23.s2.uc;
2315 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2317 #endif /* ENABLE_VERIFIER */
2319 disp = dseg_add_functionptr(cd, asm_handle_exception);
2320 M_ALD(REG_ITMP2, REG_PV, disp);
2321 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2323 M_NOP; /* nop ensures that XPC is less than the end */
2324 /* of basic block */
2328 case ICMD_GOTO: /* ... ==> ... */
2329 case ICMD_RET: /* ... ==> ... */
2332 codegen_add_branch_ref(cd, iptr->dst.block);
2337 case ICMD_JSR: /* ... ==> ... */
2340 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2345 case ICMD_IFNULL: /* ..., value ==> ... */
2347 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2349 codegen_add_branch_ref(cd, iptr->dst.block);
2353 case ICMD_IFNONNULL: /* ..., value ==> ... */
2355 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2357 codegen_add_branch_ref(cd, iptr->dst.block);
2361 case ICMD_IFEQ: /* ..., value ==> ... */
2363 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2364 if (iptr->sx.val.i == 0) {
2367 ICONST(REG_ITMP2, iptr->sx.val.i);
2368 M_BEQ(s1, REG_ITMP2, 0);
2370 codegen_add_branch_ref(cd, iptr->dst.block);
2374 case ICMD_IFLT: /* ..., value ==> ... */
2376 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2377 if (iptr->sx.val.i == 0) {
2380 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2381 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2383 ICONST(REG_ITMP2, iptr->sx.val.i);
2384 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2386 M_BNEZ(REG_ITMP1, 0);
2388 codegen_add_branch_ref(cd, iptr->dst.block);
2392 case ICMD_IFLE: /* ..., value ==> ... */
2394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2395 if (iptr->sx.val.i == 0) {
2398 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2399 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2400 M_BNEZ(REG_ITMP1, 0);
2402 ICONST(REG_ITMP2, iptr->sx.val.i);
2403 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2404 M_BEQZ(REG_ITMP1, 0);
2407 codegen_add_branch_ref(cd, iptr->dst.block);
2411 case ICMD_IFNE: /* ..., value ==> ... */
2413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2414 if (iptr->sx.val.i == 0) {
2417 ICONST(REG_ITMP2, iptr->sx.val.i);
2418 M_BNE(s1, REG_ITMP2, 0);
2420 codegen_add_branch_ref(cd, iptr->dst.block);
2424 case ICMD_IFGT: /* ..., value ==> ... */
2426 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2427 if (iptr->sx.val.i == 0) {
2430 if ((iptr->sx.val.i >= -32769) && (iptr->sx.val.i <= 32766)) {
2431 M_CMPLT_IMM(s1, iptr->sx.val.i + 1, REG_ITMP1);
2432 M_BEQZ(REG_ITMP1, 0);
2434 ICONST(REG_ITMP2, iptr->sx.val.i);
2435 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2436 M_BNEZ(REG_ITMP1, 0);
2439 codegen_add_branch_ref(cd, iptr->dst.block);
2443 case ICMD_IFGE: /* ..., value ==> ... */
2445 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2446 if (iptr->sx.val.i == 0) {
2449 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767)) {
2450 M_CMPLT_IMM(s1, iptr->sx.val.i, REG_ITMP1);
2452 ICONST(REG_ITMP2, iptr->sx.val.i);
2453 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2455 M_BEQZ(REG_ITMP1, 0);
2457 codegen_add_branch_ref(cd, iptr->dst.block);
2461 case ICMD_IF_LEQ: /* ..., value ==> ... */
2463 #if SIZEOF_VOID_P == 8
2464 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2465 if (iptr->sx.val.l == 0) {
2468 LCONST(REG_ITMP2, iptr->sx.val.l);
2469 M_BEQ(s1, REG_ITMP2, 0);
2472 if (iptr->sx.val.l == 0) {
2473 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2474 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2475 M_BEQZ(REG_ITMP3, 0);
2478 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2479 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2480 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2481 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2482 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2483 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2484 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2485 M_BEQZ(REG_ITMP3, 0);
2488 codegen_add_branch_ref(cd, iptr->dst.block);
2492 case ICMD_IF_LLT: /* ..., value ==> ... */
2494 #if SIZEOF_VOID_P == 8
2495 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2496 if (iptr->sx.val.l == 0) {
2499 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2500 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2502 LCONST(REG_ITMP2, iptr->sx.val.l);
2503 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2505 M_BNEZ(REG_ITMP1, 0);
2508 if (iptr->sx.val.l == 0) {
2509 /* if high word is less than zero, the whole long is too */
2510 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2514 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2515 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2516 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2517 M_BNEZ(REG_ITMP3, 0);
2518 codegen_add_branch_ref(cd, iptr->dst.block);
2520 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2521 M_BNE(s1, REG_ITMP2, 5);
2523 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2524 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2525 M_BNEZ(REG_ITMP3, 0);
2528 codegen_add_branch_ref(cd, iptr->dst.block);
2532 case ICMD_IF_LLE: /* ..., value ==> ... */
2534 #if SIZEOF_VOID_P == 8
2535 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2536 if (iptr->sx.val.l == 0) {
2539 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2540 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2541 M_BNEZ(REG_ITMP1, 0);
2543 LCONST(REG_ITMP2, iptr->sx.val.l);
2544 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2545 M_BEQZ(REG_ITMP1, 0);
2549 if (iptr->sx.val.l == 0) {
2550 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2551 M_BGTZ(GET_HIGH_REG(s1), 5);
2553 M_BLTZ(GET_HIGH_REG(s1), 0);
2554 codegen_add_branch_ref(cd, iptr->dst.block);
2556 M_BEQZ(GET_LOW_REG(s1), 0);
2559 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2560 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2561 M_CMPLT(s1, REG_ITMP2, REG_ITMP3);
2562 M_BNEZ(REG_ITMP3, 0);
2563 codegen_add_branch_ref(cd, iptr->dst.block);
2565 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2566 M_BNE(s1, REG_ITMP2, 5);
2568 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2569 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2570 M_BEQZ(REG_ITMP3, 0);
2573 codegen_add_branch_ref(cd, iptr->dst.block);
2577 case ICMD_IF_LNE: /* ..., value ==> ... */
2579 #if SIZEOF_VOID_P == 8
2580 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2581 if (iptr->sx.val.l == 0) {
2584 LCONST(REG_ITMP2, iptr->sx.val.l);
2585 M_BNE(s1, REG_ITMP2, 0);
2588 if (iptr->sx.val.l == 0) {
2589 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2590 M_OR(GET_LOW_REG(s1), GET_HIGH_REG(s1), REG_ITMP3);
2591 M_BNEZ(REG_ITMP3, 0);
2594 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2595 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2596 M_XOR(s1, REG_ITMP2, REG_ITMP2);
2597 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2598 ICONST(REG_ITMP3, iptr->sx.val.l & 0xffffffff);
2599 M_XOR(s1, REG_ITMP3, REG_ITMP3);
2600 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP3);
2601 M_BNEZ(REG_ITMP3, 0);
2604 codegen_add_branch_ref(cd, iptr->dst.block);
2608 case ICMD_IF_LGT: /* ..., value ==> ... */
2610 #if SIZEOF_VOID_P == 8
2611 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2612 if (iptr->sx.val.l == 0) {
2615 if ((iptr->sx.val.l >= -32769) && (iptr->sx.val.l <= 32766)) {
2616 M_CMPLT_IMM(s1, iptr->sx.val.l + 1, REG_ITMP1);
2617 M_BEQZ(REG_ITMP1, 0);
2619 LCONST(REG_ITMP2, iptr->sx.val.l);
2620 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2621 M_BNEZ(REG_ITMP1, 0);
2625 if (iptr->sx.val.l == 0) {
2626 s1 = emit_load_s1(jd, iptr, REG_ITMP12_PACKED);
2627 M_BGTZ(GET_HIGH_REG(s1), 0);
2628 codegen_add_branch_ref(cd, iptr->dst.block);
2630 M_BLTZ(GET_HIGH_REG(s1), 3);
2632 M_BNEZ(GET_LOW_REG(s1), 0);
2635 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2636 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2637 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2638 M_BNEZ(REG_ITMP3, 0);
2639 codegen_add_branch_ref(cd, iptr->dst.block);
2641 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2642 M_BNE(s1, REG_ITMP2, 5);
2644 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2645 M_CMPUGT(s2, REG_ITMP2, REG_ITMP3);
2646 M_BNEZ(REG_ITMP3, 0);
2649 codegen_add_branch_ref(cd, iptr->dst.block);
2653 case ICMD_IF_LGE: /* ..., value ==> ... */
2655 #if SIZEOF_VOID_P == 8
2656 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2657 if (iptr->sx.val.l == 0) {
2660 if ((iptr->sx.val.l >= -32768) && (iptr->sx.val.l <= 32767)) {
2661 M_CMPLT_IMM(s1, iptr->sx.val.l, REG_ITMP1);
2663 LCONST(REG_ITMP2, iptr->sx.val.l);
2664 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2666 M_BEQZ(REG_ITMP1, 0);
2669 if (iptr->sx.val.l == 0) {
2670 /* if high word is greater equal zero, the whole long is too */
2671 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2675 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2676 ICONST(REG_ITMP2, iptr->sx.val.l >> 32);
2677 M_CMPGT(s1, REG_ITMP2, REG_ITMP3);
2678 M_BNEZ(REG_ITMP3, 0);
2679 codegen_add_branch_ref(cd, iptr->dst.block);
2681 s2 = emit_load_s1_low(jd, iptr, REG_ITMP3);
2682 M_BNE(s1, REG_ITMP2, 5);
2684 ICONST(REG_ITMP2, iptr->sx.val.l & 0xffffffff);
2685 M_CMPULT(s2, REG_ITMP2, REG_ITMP3);
2686 M_BEQZ(REG_ITMP3, 0);
2689 codegen_add_branch_ref(cd, iptr->dst.block);
2693 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2694 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2695 #if SIZEOF_VOID_P == 8
2696 case ICMD_IF_LCMPEQ:
2699 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2700 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2702 codegen_add_branch_ref(cd, iptr->dst.block);
2706 #if SIZEOF_VOID_P == 4
2707 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2708 /* op1 = target JavaVM pc */
2710 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2711 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2714 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2715 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2717 codegen_add_branch_ref(cd, iptr->dst.block);
2722 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2723 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2724 #if SIZEOF_VOID_P == 8
2725 case ICMD_IF_LCMPNE:
2728 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2729 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2731 codegen_add_branch_ref(cd, iptr->dst.block);
2735 #if SIZEOF_VOID_P == 4
2736 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2738 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2739 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2741 codegen_add_branch_ref(cd, iptr->dst.block);
2743 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2744 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2746 codegen_add_branch_ref(cd, iptr->dst.block);
2751 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2752 #if SIZEOF_VOID_P == 8
2753 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2756 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2757 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2758 M_CMPLT(s1, s2, REG_ITMP3);
2759 M_BNEZ(REG_ITMP3, 0);
2760 codegen_add_branch_ref(cd, iptr->dst.block);
2764 #if SIZEOF_VOID_P == 4
2765 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2767 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2768 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2769 M_CMPLT(s1, s2, REG_ITMP3);
2770 M_BNEZ(REG_ITMP3, 0);
2771 codegen_add_branch_ref(cd, iptr->dst.block);
2773 M_CMPGT(s1, s2, REG_ITMP3);
2774 /* load low-bits before the branch, so we know the distance */
2775 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2776 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2777 M_BNEZ(REG_ITMP3, 4);
2779 M_CMPULT(s1, s2, REG_ITMP3);
2780 M_BNEZ(REG_ITMP3, 0);
2781 codegen_add_branch_ref(cd, iptr->dst.block);
2786 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2787 #if SIZEOF_VOID_P == 8
2788 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2791 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2792 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2793 M_CMPGT(s1, s2, REG_ITMP3);
2794 M_BNEZ(REG_ITMP3, 0);
2795 codegen_add_branch_ref(cd, iptr->dst.block);
2799 #if SIZEOF_VOID_P == 4
2800 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2802 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2803 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2804 M_CMPGT(s1, s2, REG_ITMP3);
2805 M_BNEZ(REG_ITMP3, 0);
2806 codegen_add_branch_ref(cd, iptr->dst.block);
2808 M_CMPLT(s1, s2, REG_ITMP3);
2809 /* load low-bits before the branch, so we know the distance */
2810 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2811 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2812 M_BNEZ(REG_ITMP3, 4);
2814 M_CMPUGT(s1, s2, REG_ITMP3);
2815 M_BNEZ(REG_ITMP3, 0);
2816 codegen_add_branch_ref(cd, iptr->dst.block);
2821 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2822 #if SIZEOF_VOID_P == 8
2823 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2826 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2827 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2828 M_CMPGT(s1, s2, REG_ITMP3);
2829 M_BEQZ(REG_ITMP3, 0);
2830 codegen_add_branch_ref(cd, iptr->dst.block);
2834 #if SIZEOF_VOID_P == 4
2835 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2837 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2838 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2839 M_CMPLT(s1, s2, REG_ITMP3);
2840 M_BNEZ(REG_ITMP3, 0);
2841 codegen_add_branch_ref(cd, iptr->dst.block);
2843 M_CMPGT(s1, s2, REG_ITMP3);
2844 /* load low-bits before the branch, so we know the distance */
2845 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2846 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2847 M_BNEZ(REG_ITMP3, 4);
2849 M_CMPUGT(s1, s2, REG_ITMP3);
2850 M_BEQZ(REG_ITMP3, 0);
2851 codegen_add_branch_ref(cd, iptr->dst.block);
2856 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2857 #if SIZEOF_VOID_P == 8
2858 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2861 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2862 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2863 M_CMPLT(s1, s2, REG_ITMP3);
2864 M_BEQZ(REG_ITMP3, 0);
2865 codegen_add_branch_ref(cd, iptr->dst.block);
2869 #if SIZEOF_VOID_P == 4
2870 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2872 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2873 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2874 M_CMPGT(s1, s2, REG_ITMP3);
2875 M_BNEZ(REG_ITMP3, 0);
2876 codegen_add_branch_ref(cd, iptr->dst.block);
2878 M_CMPLT(s1, s2, REG_ITMP3);
2879 /* load low-bits before the branch, so we know the distance */
2880 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2881 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2882 M_BNEZ(REG_ITMP3, 4);
2884 M_CMPULT(s1, s2, REG_ITMP3);
2885 M_BEQZ(REG_ITMP3, 0);
2886 codegen_add_branch_ref(cd, iptr->dst.block);
2891 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2892 #if SIZEOF_VOID_P == 8
2896 REPLACEMENT_POINT_RETURN(cd, iptr);
2897 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2898 M_INTMOVE(s1, REG_RESULT);
2899 goto nowperformreturn;
2901 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2903 REPLACEMENT_POINT_RETURN(cd, iptr);
2904 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2905 M_INTMOVE(s1, REG_RESULT);
2907 #ifdef ENABLE_VERIFIER
2908 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2909 uc = iptr->sx.s23.s2.uc;
2911 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2913 #endif /* ENABLE_VERIFIER */
2914 goto nowperformreturn;
2916 #if SIZEOF_VOID_P == 4
2917 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2919 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2920 M_LNGMOVE(s1, REG_RESULT_PACKED);
2921 goto nowperformreturn;
2924 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2925 REPLACEMENT_POINT_RETURN(cd, iptr);
2926 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2927 M_FLTMOVE(s1, REG_FRESULT);
2928 goto nowperformreturn;
2930 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2932 REPLACEMENT_POINT_RETURN(cd, iptr);
2933 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2934 M_DBLMOVE(s1, REG_FRESULT);
2935 goto nowperformreturn;
2937 case ICMD_RETURN: /* ... ==> ... */
2939 REPLACEMENT_POINT_RETURN(cd, iptr);
2945 p = cd->stackframesize;
2947 #if !defined(NDEBUG)
2948 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2949 emit_verbosecall_exit(jd);
2952 #if defined(ENABLE_THREADS)
2953 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2954 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2955 M_ALD(REG_ITMP3, REG_PV, disp);
2957 /* we need to save the proper return value */
2959 switch (iptr->opc) {
2962 #if SIZEOF_VOID_P == 8
2965 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2966 M_JSR(REG_RA, REG_ITMP3);
2967 M_AST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2969 #if SIZEOF_VOID_P == 4
2971 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2972 M_LST(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
2973 M_JSR(REG_RA, REG_ITMP3);
2979 M_ALD(REG_A0, REG_SP, rd->memuse * 8);
2980 M_JSR(REG_RA, REG_ITMP3);
2981 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2984 M_JSR(REG_RA, REG_ITMP3);
2985 M_ALD(REG_A0, REG_SP, rd->memuse * 8); /* delay*/
2989 /* and now restore the proper return value */
2991 switch (iptr->opc) {
2994 #if SIZEOF_VOID_P == 8
2997 M_ALD(REG_RESULT, REG_SP, rd->memuse * 8);
2999 #if SIZEOF_VOID_P == 4
3001 M_LLD(REG_RESULT_PACKED, REG_SP, rd->memuse * 8);
3006 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
3012 /* restore return address */
3014 if (!jd->isleafmethod) {
3015 p--; M_ALD(REG_RA, REG_SP, p * 8);
3018 /* restore saved registers */
3020 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3021 p--; M_ALD(rd->savintregs[i], REG_SP, p * 8);
3023 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3024 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3027 /* deallocate stack and return */
3029 if (cd->stackframesize) {
3032 disp = cd->stackframesize * 8;
3033 lo = (short) (disp);
3034 hi = (short) (((disp) - lo) >> 16);
3038 M_AADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
3040 M_LUI(REG_ITMP3,hi);
3041 M_AADD_IMM(REG_ITMP3,lo,REG_ITMP3);
3043 M_AADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
3056 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3059 branch_target_t *table;
3061 table = iptr->dst.table;
3063 l = iptr->sx.s23.s2.tablelow;
3064 i = iptr->sx.s23.s3.tablehigh;
3066 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3068 {M_INTMOVE(s1, REG_ITMP1);}
3069 else if (l <= 32768) {
3070 M_IADD_IMM(s1, -l, REG_ITMP1);
3073 ICONST(REG_ITMP2, l);
3074 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3077 /* number of targets */
3082 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3083 M_BEQZ(REG_ITMP2, 0);
3084 codegen_add_branch_ref(cd, table[0].block); /* default target */
3085 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot */
3087 /* build jump table top down and use address of lowest entry */
3092 dseg_add_target(cd, table->block);
3097 /* length of dataseg after last dseg_add_target is used by load */
3099 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3100 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3107 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3110 lookup_target_t *lookup;
3112 lookup = iptr->dst.lookup;
3114 i = iptr->sx.s23.s2.lookupcount;
3116 MCODECHECK((i<<2)+8);
3117 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3120 ICONST(REG_ITMP2, lookup->value);
3121 M_BEQ(s1, REG_ITMP2, 0);
3122 codegen_add_branch_ref(cd, lookup->target.block);
3128 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
3135 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3137 bte = iptr->sx.s23.s3.bte;
3141 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3143 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3144 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3145 case ICMD_INVOKEINTERFACE:
3147 REPLACEMENT_POINT_INVOKE(cd, iptr);
3149 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3151 um = iptr->sx.s23.s3.um;
3152 md = um->methodref->parseddesc.md;
3155 lm = iptr->sx.s23.s3.fmiref->p.method;
3157 md = lm->parseddesc;
3161 s3 = md->paramcount;
3163 MCODECHECK((s3 << 1) + 64);
3165 /* copy arguments to registers or stack location */
3167 for (s3 = s3 - 1; s3 >= 0; s3--) {
3168 var = VAR(iptr->sx.s23.s2.args[s3]);
3170 if (var->flags & PREALLOC)
3173 if (IS_INT_LNG_TYPE(var->type)) {
3174 #if SIZEOF_VOID_P == 8
3175 if (!md->params[s3].inmemory) {
3176 s1 = rd->argintregs[md->params[s3].regoff];
3177 d = emit_load(jd, iptr, var, s1);
3181 d = emit_load(jd, iptr, var, REG_ITMP1);
3182 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3185 if (!md->params[s3].inmemory) {
3186 if (IS_2_WORD_TYPE(var->type)) {
3187 s1 = md->params[s3].regoff;
3188 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3189 rd->argintregs[GET_HIGH_REG(s1)]);
3190 d = emit_load(jd, iptr, var, s1);
3194 s1 = rd->argintregs[md->params[s3].regoff];
3195 d = emit_load(jd, iptr, var, s1);
3200 if (IS_2_WORD_TYPE(var->type)) {
3201 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3202 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3205 d = emit_load(jd, iptr, var, REG_ITMP1);
3206 M_IST(d, REG_SP, md->params[s3].regoff * 8);
3212 if (!md->params[s3].inmemory) {
3213 #if SIZEOF_VOID_P == 8
3214 s1 = rd->argfltregs[md->params[s3].regoff];
3215 d = emit_load(jd, iptr, var, s1);
3216 if (IS_2_WORD_TYPE(var->type))
3222 ((s3 == 1) && IS_FLT_DBL_TYPE(md->paramtypes[0].type))) {
3223 s1 = rd->argfltregs[md->params[s3].regoff];
3224 d = emit_load(jd, iptr, var, s1);
3225 if (IS_2_WORD_TYPE(var->type))
3231 if (IS_2_WORD_TYPE(var->type)) {
3232 s1 = md->params[s3].regoff;
3233 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3234 rd->argintregs[GET_HIGH_REG(s1)]);
3235 d = emit_load(jd, iptr, var, REG_FTMP1);
3236 M_MFC1(GET_LOW_REG(s2), d);
3237 M_MFC1(GET_HIGH_REG(s2), d + 1);
3241 s1 = rd->argintregs[md->params[s3].regoff];
3242 d = emit_load(jd, iptr, var, s1);
3250 d = emit_load(jd, iptr, var, REG_FTMP1);
3251 if (IS_2_WORD_TYPE(var->type))
3252 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3254 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3259 switch (iptr->opc) {
3261 disp = dseg_add_functionptr(cd, bte->fp);
3263 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3265 /* TWISTI: i actually don't know the reason for using
3266 REG_ITMP3 here instead of REG_PV. */
3270 case ICMD_INVOKESPECIAL:
3271 /* emit_nullpointer_check(cd, REG_A0); */
3275 M_LUI(REG_ITMP3, 0);
3276 M_OR_IMM(REG_ITMP3, 0, REG_ITMP3);
3277 codegen_add_nullpointerexception_ref(cd);
3278 M_AADD(REG_PV, REG_ITMP3, REG_ITMP3);
3284 case ICMD_INVOKESTATIC:
3286 disp = dseg_add_unique_address(cd, um);
3288 codegen_add_patch_ref(cd, PATCHER_invokestatic_special, um,
3292 disp = dseg_add_address(cd, lm->stubroutine);
3294 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3298 case ICMD_INVOKEVIRTUAL:
3299 emit_nullpointer_check(cd, iptr, REG_A0);
3302 codegen_add_patch_ref(cd, PATCHER_invokevirtual, um, 0);
3307 s1 = OFFSET(vftbl_t, table[0]) +
3308 sizeof(methodptr) * lm->vftblindex;
3310 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3311 M_ALD(REG_PV, REG_METHODPTR, s1);
3315 case ICMD_INVOKEINTERFACE:
3316 emit_nullpointer_check(cd, iptr, REG_A0);
3319 codegen_add_patch_ref(cd, PATCHER_invokeinterface, um, 0);
3325 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3326 sizeof(methodptr*) * lm->class->index;
3328 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3331 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3332 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3333 M_ALD(REG_PV, REG_METHODPTR, s2);
3338 /* generate the actual call */
3342 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3343 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3344 M_LDA(REG_PV, REG_RA, -disp);
3346 /* actually only used for ICMD_BUILTIN */
3348 emit_exception_check(cd, iptr);
3350 /* store return value */
3352 d = md->returntype.type;
3354 if (d != TYPE_VOID) {
3355 if (IS_INT_LNG_TYPE(d)) {
3356 #if SIZEOF_VOID_P == 8
3357 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3358 M_INTMOVE(REG_RESULT, s1);
3360 if (IS_2_WORD_TYPE(d)) {
3361 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3362 M_LNGMOVE(REG_RESULT_PACKED, s1);
3365 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3366 M_INTMOVE(REG_RESULT, s1);
3371 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3372 if (IS_2_WORD_TYPE(d))
3373 M_DMOV(REG_FRESULT, s1);
3375 M_FMOV(REG_FRESULT, s1);
3377 emit_store_dst(jd, iptr, s1);
3382 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3383 /* val.a: (classinfo*) superclass */
3385 /* superclass is an interface:
3387 * OK if ((sub == NULL) ||
3388 * (sub->vftbl->interfacetablelength > super->index) &&
3389 * (sub->vftbl->interfacetable[-super->index] != NULL));
3391 * superclass is a class:
3393 * OK if ((sub == NULL) || (0
3394 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3395 * super->vftbl->diffvall));
3398 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3402 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3407 super = iptr->sx.s23.s3.c.cls;
3408 superindex = super->index;
3411 #if defined(ENABLE_THREADS)
3412 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3415 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3417 /* calculate interface checkcast code size */
3419 /* s2 = 3 + 2 + 1 + 2; */
3422 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3424 /* calculate class checkcast code size */
3426 /* s3 = 2 + 1 + 4 + 1 + 2 /\* 10 + (s1 == REG_ITMP1) *\/; */
3427 s3 = 2 + 1 + 4 + 1 + 7;
3429 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3431 /* if class is not resolved, check which code to call */
3433 if (super == NULL) {
3434 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
3437 cr = iptr->sx.s23.s3.c.ref;
3438 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3440 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3443 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3444 M_ILD(REG_ITMP2, REG_PV, disp);
3445 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3446 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3450 /* interface checkcast code */
3452 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3453 if (super == NULL) {
3454 cr = iptr->sx.s23.s3.c.ref;
3456 codegen_add_patch_ref(cd, PATCHER_checkcast_interface,
3464 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3465 M_ILD(REG_ITMP3, REG_ITMP2,
3466 OFFSET(vftbl_t, interfacetablelength));
3467 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3468 emit_classcast_check(cd, iptr, ICMD_IFLE, REG_ITMP3, s1);
3470 M_ALD(REG_ITMP3, REG_ITMP2,
3471 OFFSET(vftbl_t, interfacetable[0]) -
3472 superindex * sizeof(methodptr*));
3473 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_ITMP3, s1);
3475 if (super == NULL) {
3481 /* class checkcast code */
3483 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3484 if (super == NULL) {
3485 cr = iptr->sx.s23.s3.c.ref;
3486 disp = dseg_add_unique_address(cd, NULL);
3488 codegen_add_patch_ref(cd,
3489 PATCHER_checkcast_instanceof_class,
3493 disp = dseg_add_address(cd, super->vftbl);
3499 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3500 M_ALD(REG_ITMP3, REG_PV, disp);
3501 #if defined(ENABLE_THREADS)
3502 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3504 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3505 /* if (s1 != REG_ITMP1) { */
3506 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3507 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3508 /* #if defined(ENABLE_THREADS) */
3509 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3511 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3513 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3514 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3515 M_ALD(REG_ITMP3, REG_PV, disp);
3516 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3517 #if defined(ENABLE_THREADS)
3518 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3521 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3522 emit_classcast_check(cd, iptr, ICMD_IFNE, REG_ITMP3, s1);
3525 d = codegen_reg_of_dst(jd, iptr, s1);
3528 s1 = emit_load_s1(jd, iptr, REG_A0);
3529 M_INTMOVE(s1, REG_A0);
3531 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3532 cr = iptr->sx.s23.s3.c.ref;
3533 disp = dseg_add_unique_address(cd, NULL);
3535 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3539 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3541 M_ALD(REG_A1, REG_PV, disp);
3542 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3543 M_ALD(REG_ITMP3, REG_PV, disp);
3544 M_JSR(REG_RA, REG_ITMP3);
3547 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3548 emit_classcast_check(cd, iptr, ICMD_IFEQ, REG_RESULT, s1);
3550 d = codegen_reg_of_dst(jd, iptr, s1);
3554 emit_store_dst(jd, iptr, d);
3557 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3558 /* val.a: (classinfo*) superclass */
3560 /* superclass is an interface:
3562 * return (sub != NULL) &&
3563 * (sub->vftbl->interfacetablelength > super->index) &&
3564 * (sub->vftbl->interfacetable[-super->index] != NULL);
3566 * superclass is a class:
3568 * return ((sub != NULL) && (0
3569 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3570 * super->vftbl->diffvall));
3577 super = iptr->sx.s23.s3.c.cls;
3579 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3584 super = iptr->sx.s23.s3.c.cls;
3585 superindex = super->index;
3588 #if defined(ENABLE_THREADS)
3589 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3592 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3593 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3595 M_MOV(s1, REG_ITMP1);
3599 /* calculate interface instanceof code size */
3603 s2 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3605 /* calculate class instanceof code size */
3609 s3 += (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0);
3613 /* if class is not resolved, check which code to call */
3615 if (super == NULL) {
3616 M_BEQZ(s1, 5 + (opt_shownops ? PATCHER_CALL_INSTRUCTIONS : 0) + s2 + 2 + s3);
3619 cr = iptr->sx.s23.s3.c.ref;
3620 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3622 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3625 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3626 M_ILD(REG_ITMP3, REG_PV, disp);
3627 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3628 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3632 /* interface instanceof code */
3634 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3635 if (super == NULL) {
3636 cr = iptr->sx.s23.s3.c.ref;
3638 codegen_add_patch_ref(cd, PATCHER_instanceof_interface,
3646 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3647 M_ILD(REG_ITMP3, REG_ITMP1,
3648 OFFSET(vftbl_t, interfacetablelength));
3649 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3650 M_BLEZ(REG_ITMP3, 3);
3652 M_ALD(REG_ITMP1, REG_ITMP1,
3653 OFFSET(vftbl_t, interfacetable[0]) -
3654 superindex * sizeof(methodptr*));
3655 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3657 if (super == NULL) {
3663 /* class instanceof code */
3665 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3666 if (super == NULL) {
3667 cr = iptr->sx.s23.s3.c.ref;
3668 disp = dseg_add_unique_address(cd, NULL);
3670 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_class,
3674 disp = dseg_add_address(cd, super->vftbl);
3680 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3681 M_ALD(REG_ITMP2, REG_PV, disp);
3682 #if defined(ENABLE_THREADS)
3683 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3685 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3686 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3687 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3688 #if defined(ENABLE_THREADS)
3689 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3691 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3692 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3695 emit_store_dst(jd, iptr, d);
3699 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3701 /* check for negative sizes and copy sizes to stack if necessary */
3703 MCODECHECK((iptr->s1.argcount << 1) + 64);
3705 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3707 var = VAR(iptr->sx.s23.s2.args[s1]);
3709 /* copy SAVEDVAR sizes to stack */
3711 if (!(var->flags & PREALLOC)) {
3712 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3713 #if SIZEOF_VOID_P == 8
3714 M_LST(s2, REG_SP, s1 * 8);
3716 M_IST(s2, REG_SP, (s1 + 2) * 8);
3721 /* a0 = dimension count */
3723 ICONST(REG_A0, iptr->s1.argcount);
3725 /* is patcher function set? */
3727 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3728 cr = iptr->sx.s23.s3.c.ref;
3729 disp = dseg_add_unique_address(cd, NULL);
3731 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3735 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3737 /* a1 = arraydescriptor */
3739 M_ALD(REG_A1, REG_PV, disp);
3741 /* a2 = pointer to dimensions = stack pointer */
3743 #if SIZEOF_VOID_P == 8
3744 M_MOV(REG_SP, REG_A2);
3746 M_AADD_IMM(REG_SP, 4*4, REG_A2);
3749 disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
3750 M_ALD(REG_ITMP3, REG_PV, disp);
3751 M_JSR(REG_RA, REG_ITMP3);
3754 /* check for exception before result assignment */
3756 emit_exception_check(cd, iptr);
3758 d = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3759 M_INTMOVE(REG_RESULT, d);
3760 emit_store_dst(jd, iptr, d);
3764 exceptions_throw_internalerror("Unknown ICMD %d during code generation",
3769 } /* for instruction */
3771 MCODECHECK(64); /* XXX require smaller number? */
3773 /* At the end of a basic block we may have to append some nops,
3774 because the patcher stub calling code might be longer than the
3775 actual instruction. So codepatching does not change the
3776 following block unintentionally. */
3778 if (cd->mcodeptr < cd->lastmcodeptr) {
3779 while (cd->mcodeptr < cd->lastmcodeptr)
3783 } /* if (bptr -> flags >= BBREACHED) */
3784 } /* for basic block */
3786 dseg_createlinenumbertable(cd);
3788 /* generate exception and patcher stubs */
3790 emit_exception_stubs(jd);
3791 emit_patcher_stubs(jd);
3792 REPLACEMENT_EMIT_STUBS(jd);
3796 /* everything's ok */
3802 /* createcompilerstub **********************************************************
3804 Creates a stub routine which calls the compiler.
3806 *******************************************************************************/
3808 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3809 #define COMPILERSTUB_CODESIZE 4 * 4
3811 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3814 u1 *createcompilerstub(methodinfo *m)
3816 u1 *s; /* memory to hold the stub */
3822 s = CNEW(u1, COMPILERSTUB_SIZE);
3824 /* set data pointer and code pointer */
3827 s = s + COMPILERSTUB_DATASIZE;
3829 /* mark start of dump memory area */
3831 dumpsize = dump_size();
3833 cd = DNEW(codegendata);
3836 /* Store the codeinfo pointer in the same place as in the
3837 methodheader for compiled methods. */
3839 code = code_codeinfo_new(m);
3841 d[0] = (ptrint) asm_call_jit_compiler;
3843 d[2] = (ptrint) code;
3845 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
3846 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
3850 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
3852 #if defined(ENABLE_STATISTICS)
3854 count_cstub_len += COMPILERSTUB_SIZE;
3857 /* release dump area */
3859 dump_release(dumpsize);
3865 /* createnativestub ************************************************************
3867 Creates a stub routine which calls a native method.
3869 *******************************************************************************/
3871 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3879 s4 i, j; /* count variables */
3882 s4 funcdisp; /* displacement of the function */
3884 /* get required compiler data */
3891 /* initialize variables */
3894 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3896 /* calculate stack frame size */
3898 cd->stackframesize =
3899 1 + /* return address */
3900 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3901 sizeof(localref_table) / SIZEOF_VOID_P +
3902 md->paramcount + /* for saving arguments over calls */
3903 #if SIZEOF_VOID_P == 4
3904 5 + /* additional save space (MIPS32) */
3906 1 + /* for saving return address */
3909 /* adjust stackframe size for 16-byte alignment */
3911 if (cd->stackframesize & 1)
3912 cd->stackframesize++;
3914 /* create method header */
3916 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3917 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3918 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3919 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3920 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3921 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3922 (void) dseg_addlinenumbertablesize(cd);
3923 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3925 /* generate stub code */
3927 M_LDA(REG_SP, REG_SP, -cd->stackframesize * 8); /* build up stackframe */
3928 M_AST(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* store RA */
3930 #if !defined(NDEBUG)
3931 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3932 emit_verbosecall_enter(jd);
3935 /* get function address (this must happen before the stackframeinfo) */
3937 funcdisp = dseg_add_functionptr(cd, f);
3939 #if !defined(WITH_STATIC_CLASSPATH)
3941 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, funcdisp);
3944 /* save integer and float argument registers */
3946 #if SIZEOF_VOID_P == 8
3947 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3948 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3949 M_AST(rd->argintregs[i], REG_SP, j * 8);
3954 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
3955 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3956 if (!md->params[i].inmemory) {
3957 s1 = md->params[i].regoff;
3958 if (IS_2_WORD_TYPE(md->params[i].type)) {
3959 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
3960 rd->argintregs[GET_HIGH_REG(s1)]);
3961 M_LST(s1, REG_SP, j * 8);
3964 M_IST(rd->argintregs[s1], REG_SP, j * 8);
3972 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
3973 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
3974 if (IS_2_WORD_TYPE(md->params[i].type))
3975 M_DST(rd->argfltregs[i], REG_SP, j * 8);
3977 M_FST(rd->argfltregs[i], REG_SP, j * 8);
3982 /* prepare data structures for native function call */
3984 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
3985 M_MOV(REG_PV, REG_A1);
3986 M_AADD_IMM(REG_SP, cd->stackframesize * 8, REG_A2);
3987 M_ALD(REG_A3, REG_SP, (cd->stackframesize - 1) * 8);
3988 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3989 M_ALD(REG_ITMP3, REG_PV, disp);
3990 M_JSR(REG_RA, REG_ITMP3);
3991 M_NOP; /* XXX fill me! */
3993 /* restore integer and float argument registers */
3995 #if SIZEOF_VOID_P == 8
3996 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
3997 if (IS_INT_LNG_TYPE(md->params[i].type)) {
3998 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4003 for (i = 0, j = 5; i < md->paramcount && i < INT_ARG_CNT; i++) {
4004 if (IS_INT_LNG_TYPE(md->params[i].type)) {
4005 if (!md->params[i].inmemory) {
4006 s1 = md->params[i].regoff;
4007 if (IS_2_WORD_TYPE(md->params[i].type)) {
4008 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
4009 rd->argintregs[GET_HIGH_REG(s1)]);
4010 M_LLD(s1, REG_SP, j * 8);
4013 M_ILD(rd->argintregs[s1], REG_SP, j * 8);
4021 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4022 if (IS_FLT_DBL_TYPE(md->params[i].type)) {
4023 if (IS_2_WORD_TYPE(md->params[i].type))
4024 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4026 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4031 /* copy or spill arguments to new locations */
4033 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4034 t = md->params[i].type;
4036 if (IS_INT_LNG_TYPE(t)) {
4037 if (!md->params[i].inmemory) {
4038 s1 = md->params[i].regoff;
4039 #if SIZEOF_VOID_P == 8
4040 s1 = rd->argintregs[s1];
4042 if (IS_2_WORD_TYPE(t))
4043 s1 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
4044 rd->argintregs[GET_HIGH_REG(s1)]);
4046 s1 = rd->argintregs[s1];
4049 if (!nmd->params[j].inmemory) {
4050 s2 = nmd->params[j].regoff;
4051 #if SIZEOF_VOID_P == 8
4052 s2 = rd->argintregs[s2];
4055 if (IS_2_WORD_TYPE(t)) {
4056 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
4057 rd->argintregs[GET_HIGH_REG(s2)]);
4061 s2 = rd->argintregs[s2];
4067 s2 = nmd->params[j].regoff;
4069 #if SIZEOF_VOID_P == 8
4070 M_LST(s1, REG_SP, s2 * 8);
4072 if (IS_2_WORD_TYPE(t))
4073 M_LST(s1, REG_SP, s2 * 4);
4075 M_IST(s1, REG_SP, s2 * 4);
4080 s1 = md->params[i].regoff + cd->stackframesize;
4081 s2 = nmd->params[j].regoff;
4083 #if SIZEOF_VOID_P == 8
4084 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4085 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4087 if (IS_2_WORD_TYPE(t)) {
4088 M_LLD(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s1 * 8);
4089 M_LST(PACK_REGS(REG_ITMP1, REG_ITMP2), REG_SP, s2 * 4);
4092 M_ILD(REG_ITMP1, REG_SP, s1 * 8);
4093 M_IST(REG_ITMP1, REG_SP, s2 * 4);
4099 if (!md->params[i].inmemory) {
4100 s1 = md->params[i].regoff;
4101 s2 = nmd->params[j].regoff;
4103 if (!nmd->params[j].inmemory) {
4104 #if SIZEOF_VOID_P == 8
4105 s1 = rd->argfltregs[s1];
4106 s2 = rd->argfltregs[s2];
4107 if (IS_2_WORD_TYPE(t))
4112 /* On MIPS32 float arguments for native functions
4113 can never be in float argument registers, since
4114 the first argument is _always_ an integer
4115 argument (JNIenv) */
4117 if (IS_2_WORD_TYPE(t)) {
4118 s1 = rd->argfltregs[s1];
4119 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s2)],
4120 rd->argintregs[GET_HIGH_REG(s2)]);
4122 /* double high/low order is endian
4123 independent: even numbered holds low
4124 32-bits, odd numbered high 32-bits */
4126 M_MFC1(GET_LOW_REG(s2), s1); /* low 32-bits */
4127 M_MFC1(GET_HIGH_REG(s2), s1 + 1); /* high 32-bits */
4130 s1 = rd->argfltregs[s1];
4131 s2 = rd->argintregs[s2];
4137 #if SIZEOF_VOID_P == 8
4138 s1 = rd->argfltregs[s1];
4140 if (IS_2_WORD_TYPE(t))
4141 M_DST(s1, REG_SP, s2 * 8);
4143 M_FST(s1, REG_SP, s2 * 8);
4145 /* s1 may have been originally in 2 int registers,
4146 but was moved out by the native function
4147 argument(s), just get low register */
4149 s1 = rd->argfltregs[GET_LOW_REG(s1)];
4151 if (IS_2_WORD_TYPE(t))
4152 M_DST(s1, REG_SP, s2 * 4);
4154 M_FST(s1, REG_SP, s2 * 4);
4159 s1 = md->params[i].regoff + cd->stackframesize;
4160 s2 = nmd->params[j].regoff;
4162 if (IS_2_WORD_TYPE(t)) {
4163 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4164 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4167 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4168 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4174 /* put class into second argument register */
4176 if (m->flags & ACC_STATIC) {
4177 disp = dseg_add_address(cd, m->class);
4178 M_ALD(REG_A1, REG_PV, disp);
4181 /* put env into first argument register */
4183 disp = dseg_add_address(cd, _Jv_env);
4184 M_ALD(REG_A0, REG_PV, disp);
4186 /* do the native function call */
4188 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4189 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4190 M_NOP; /* delay slot */
4192 /* save return value */
4194 if (md->returntype.type != TYPE_VOID) {
4195 #if SIZEOF_VOID_P == 8
4196 if (IS_INT_LNG_TYPE(md->returntype.type))
4197 M_LST(REG_RESULT, REG_SP, 0 * 8);
4199 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4201 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4202 M_IST(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4203 if (IS_2_WORD_TYPE(md->returntype.type))
4204 M_IST(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4207 M_DST(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4211 #if !defined(NDEBUG)
4212 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
4213 emit_verbosecall_exit(jd);
4216 /* remove native stackframe info */
4218 M_AADD_IMM(REG_SP, (cd->stackframesize - 1) * 8, REG_A0);
4219 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
4220 M_ALD(REG_ITMP3, REG_PV, disp);
4221 M_JSR(REG_RA, REG_ITMP3);
4222 M_NOP; /* XXX fill me! */
4223 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4225 /* restore return value */
4227 if (md->returntype.type != TYPE_VOID) {
4228 #if SIZEOF_VOID_P == 8
4229 if (IS_INT_LNG_TYPE(md->returntype.type))
4230 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4232 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4234 if (IS_INT_LNG_TYPE(md->returntype.type)) {
4235 M_ILD(REG_RESULT, REG_SP, 1*4 + 0 * 8);
4236 if (IS_2_WORD_TYPE(md->returntype.type))
4237 M_ILD(REG_RESULT2, REG_SP, 1*4 + 0 * 8 + 4);
4240 M_DLD(REG_FRESULT, REG_SP, 1*4 + 0 * 8);
4244 M_ALD(REG_RA, REG_SP, (cd->stackframesize - 1) * 8); /* load RA */
4246 /* check for exception */
4248 M_BNEZ(REG_ITMP1_XPTR, 2); /* if no exception then return */
4249 M_LDA(REG_SP, REG_SP, cd->stackframesize * 8); /* DELAY SLOT */
4251 M_RET(REG_RA); /* return to caller */
4252 M_NOP; /* DELAY SLOT */
4254 /* handle exception */
4256 disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
4257 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4258 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4259 M_ASUB_IMM(REG_RA, 4, REG_ITMP2_XPC); /* get exception address (DELAY) */
4261 /* generate patcher stubs */
4263 emit_patcher_stubs(jd);
4267 return code->entrypoint;
4272 * These are local overrides for various environment variables in Emacs.
4273 * Please do not remove this and leave it at the end of the file, where
4274 * Emacs will automagically detect them.
4275 * ---------------------------------------------------------------------
4278 * indent-tabs-mode: t
4282 * vim:noexpandtab:sw=4:ts=4: