1 /* src/vm/jit/x86_64/codegen.c - machine code generator for x86_64
3 Copyright (C) 1996-2005, 2006 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
32 $Id: codegen.c 7300 2007-02-07 22:06:53Z pm $
46 #include "vm/jit/s390/arch.h"
47 #include "vm/jit/s390/codegen.h"
48 #include "vm/jit/s390/emit.h"
50 #include "mm/memory.h"
51 #include "native/jni.h"
52 #include "native/native.h"
54 #if defined(ENABLE_THREADS)
55 # include "threads/native/lock.h"
58 #include "vm/builtin.h"
59 #include "vm/exceptions.h"
60 #include "vm/global.h"
61 #include "vm/loader.h"
62 #include "vm/options.h"
63 #include "vm/statistics.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/methodheader.h"
72 #include "vm/jit/parse.h"
73 #include "vm/jit/patcher.h"
74 #include "vm/jit/reg.h"
75 #include "vm/jit/replace.h"
77 #if defined(ENABLE_LSRA)
78 # include "vm/jit/allocator/lsra.h"
81 #define OOPS() assert(0);
84 u1 *createcompilerstub(methodinfo *m) {
93 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) {
95 return createcompilerstub(NULL);
101 /* codegen *********************************************************************
103 Generates machine code.
105 *******************************************************************************/
108 bool codegen(jitdata *jd)
114 s4 len, s1, s2, s3, d, disp;
117 varinfo *var, *var1, *var2, *dst;
121 constant_classref *cr;
122 unresolved_class *uc;
123 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
124 unresolved_method *um;
125 builtintable_entry *bte;
128 unresolved_field *uf;
131 rplpoint *replacementpoint;
135 /* get required compiler data */
142 /* prevent compiler warnings */
153 savedregs_num = 1; /* space to save RA */
155 /* space to save used callee saved registers */
157 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
158 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
160 cd->stackframesize = rd->memuse + savedregs_num;
163 * As REG_ITMP3 == REG_RA, do not touch REG_ITMP3, until it has been saved.
166 #if defined(ENABLE_THREADS)
167 /* space to save argument of monitor_enter */
168 OOPS(); /* see powerpc */
170 if (checksync && (m->flags & ACC_SYNCHRONIZED))
171 cd->stackframesize++;
175 /* Keep stack of non-leaf functions 16-byte aligned for calls into
176 native code e.g. libc or jni (alignment problems with
179 if (!jd->isleafmethod || opt_verbosecall)
180 /* TODO really 16 bytes ? */
181 cd->stackframesize = (cd->stackframesize + 3) & ~3;
183 /* create method header */
185 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
186 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
188 #if defined(ENABLE_THREADS)
189 /* IsSync contains the offset relative to the stack pointer for the
190 argument of monitor_exit used in the exception handler. Since the
191 offset could be zero and give a wrong meaning of the flag it is
195 if (checksync && (m->flags & ACC_SYNCHRONIZED))
196 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync */
199 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
201 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
202 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
203 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
205 (void) dseg_addlinenumbertablesize(cd);
207 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
209 /* create exception table */
211 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
212 dseg_add_target(cd, ex->start);
213 dseg_add_target(cd, ex->end);
214 dseg_add_target(cd, ex->handler);
215 (void) dseg_add_unique_address(cd, ex->catchtype.any);
218 /* generate method profiling code */
220 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
221 /* count frequency */
223 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
224 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
225 M_IADD_IMM(1, REG_ITMP2);
226 M_IST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
228 /* PROFILE_CYCLE_START; */
231 /* create stack frame (if necessary) */
233 if (cd->stackframesize)
234 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
236 /* save used callee saved registers and return address */
238 p = cd->stackframesize;
239 p--; M_AST(REG_RA, REG_SP, p * 4);
240 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
241 p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
243 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
244 p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
247 /* take arguments out of register or stack frame */
251 for (p = 0, l = 0; p < md->paramcount; p++) {
252 t = md->paramtypes[p].type;
253 varindex = jd->local_map[l * 5 + t];
256 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
259 if (varindex == UNUSED)
264 s1 = md->params[p].regoff;
265 if (IS_INT_LNG_TYPE(t)) { /* integer args */
266 if (IS_2_WORD_TYPE(t))
267 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
268 rd->argintregs[GET_HIGH_REG(s1)]);
270 s2 = rd->argintregs[s1];
271 if (!md->params[p].inmemory) { /* register arguments */
272 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
273 if (IS_2_WORD_TYPE(t))
274 M_LNGMOVE(s2, var->vv.regoff);
276 M_INTMOVE(s2, var->vv.regoff);
278 } else { /* reg arg -> spilled */
279 if (IS_2_WORD_TYPE(t))
280 M_LST(s2, REG_SP, var->vv.regoff * 4);
282 M_IST(s2, REG_SP, var->vv.regoff * 4);
285 } else { /* stack arguments */
286 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
287 if (IS_2_WORD_TYPE(t))
288 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
290 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
292 } else { /* stack arg -> spilled */
293 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
294 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
295 if (IS_2_WORD_TYPE(t)) {
296 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
297 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
302 } else { /* floating args */
303 if (!md->params[p].inmemory) { /* register arguments */
304 s2 = rd->argfltregs[s1];
305 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
306 M_FLTMOVE(s2, var->vv.regoff);
308 } else { /* reg arg -> spilled */
309 if (IS_2_WORD_TYPE(t))
310 M_DST(s2, REG_SP, var->vv.regoff * 4);
312 M_FST(s2, REG_SP, var->vv.regoff * 4);
315 } else { /* stack arguments */
316 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
317 if (IS_2_WORD_TYPE(t))
318 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
321 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
323 } else { /* stack-arg -> spilled */
324 if (IS_2_WORD_TYPE(t)) {
325 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
326 M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
327 var->vv.regoff = cd->stackframesize + s1;
330 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
331 M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
338 /* save monitorenter argument */
340 #if defined(ENABLE_THREADS)
341 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
342 /* stack offset for monitor argument */
346 if (opt_verbosecall) {
347 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
349 for (p = 0; p < INT_ARG_CNT; p++)
350 M_LST(rd->argintregs[p], REG_SP, p * 8);
352 for (p = 0; p < FLT_ARG_CNT; p++)
353 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
355 s1 += INT_ARG_CNT + FLT_ARG_CNT;
358 /* decide which monitor enter function to call */
360 if (m->flags & ACC_STATIC) {
361 M_MOV_IMM(&m->class->object.header, REG_A0);
366 codegen_add_nullpointerexception_ref(cd);
369 M_AST(REG_A0, REG_SP, s1 * 8);
370 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
373 if (opt_verbosecall) {
374 for (p = 0; p < INT_ARG_CNT; p++)
375 M_LLD(rd->argintregs[p], REG_SP, p * 8);
377 for (p = 0; p < FLT_ARG_CNT; p++)
378 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
380 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
386 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
387 emit_verbosecall_enter(jd);
388 #endif /* !defined(NDEBUG) */
392 /* end of header generation */
394 replacementpoint = jd->code->rplpoints;
397 /* walk through all basic blocks */
399 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
401 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
403 if (bptr->flags >= BBREACHED) {
405 /* branch resolving */
407 codegen_resolve_branchrefs(cd, bptr);
409 /* handle replacement points */
412 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
413 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
417 assert(cd->lastmcodeptr <= cd->mcodeptr);
418 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
422 /* copy interface registers to their destination */
427 /* generate basicblock profiling code */
429 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
430 /* count frequency */
432 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
433 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
435 /* if this is an exception handler, start profiling again */
437 if (bptr->type == BBTYPE_EXH)
441 #if defined(ENABLE_LSRA)
445 src = bptr->invars[len];
446 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
447 if (bptr->type == BBTYPE_EXH) {
448 /* d = reg_of_var(rd, src, REG_ITMP1); */
449 if (!IS_INMEMORY(src->flags))
453 M_INTMOVE(REG_ITMP1, d);
454 emit_store(jd, NULL, src, d);
464 var = VAR(bptr->invars[len]);
465 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
466 if (bptr->type == BBTYPE_EXH) {
467 d = codegen_reg_of_var(0, var, REG_ITMP1);
468 M_INTMOVE(REG_ITMP1, d);
469 emit_store(jd, NULL, var, d);
473 assert((var->flags & INOUT));
476 #if defined(ENABLE_LSRA)
479 /* walk through all instructions */
484 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
485 if (iptr->line != currentline) {
486 dseg_addlinenumber(cd, iptr->line);
487 currentline = iptr->line;
490 MCODECHECK(1024); /* 1KB should be enough */
493 case ICMD_NOP: /* ... ==> ... */
494 case ICMD_POP: /* ..., value ==> ... */
495 case ICMD_POP2: /* ..., value, value ==> ... */
496 case ICMD_INLINE_START: /* internal ICMDs */
497 case ICMD_INLINE_END:
500 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
503 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
506 codegen_add_nullpointerexception_ref(cd);
510 /* constant operations ************************************************/
512 case ICMD_ICONST: /* ... ==> ..., constant */
513 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
514 ICONST(d, iptr->sx.val.i);
515 emit_store_dst(jd, iptr, d);
518 case ICMD_LCONST: /* ... ==> ..., constant */
521 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
522 LCONST(d, iptr->sx.val.l);
523 emit_store_dst(jd, iptr, d);
527 case ICMD_FCONST: /* ... ==> ..., constant */
530 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
531 disp = dseg_add_float(cd, iptr->sx.val.f);
532 emit_movdl_membase_reg(cd, RIP, -((cd->mcodeptr + ((d > 7) ? 9 : 8)) - cd->mcodebase) + disp, d);
533 emit_store_dst(jd, iptr, d);
537 case ICMD_DCONST: /* ... ==> ..., constant */
540 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
541 disp = dseg_add_double(cd, iptr->sx.val.d);
542 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
543 emit_store_dst(jd, iptr, d);
547 case ICMD_ACONST: /* ... ==> ..., constant */
548 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
550 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
551 cr = iptr->sx.val.c.ref;
552 disp = dseg_add_unique_address(cd, NULL);
554 /* PROFILE_CYCLE_STOP; */
556 codegen_add_patch_ref(cd, PATCHER_aconst, cr, disp);
558 /* PROFILE_CYCLE_START; */
560 M_ALD(d, REG_PV, disp);
562 if (iptr->sx.val.anyptr == 0) {
565 disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
566 M_ALD(d, REG_PV, disp);
569 emit_store_dst(jd, iptr, d);
573 /* load/store/copy/move operations ************************************/
575 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
576 case ICMD_ALOAD: /* s1 = local variable */
580 case ICMD_ISTORE: /* ..., value ==> ... */
586 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
590 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
591 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
594 /* integer operations *************************************************/
596 case ICMD_INEG: /* ..., value ==> ..., - value */
599 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
603 emit_store_dst(jd, iptr, d);
607 case ICMD_LNEG: /* ..., value ==> ..., - value */
610 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
611 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
614 emit_store_dst(jd, iptr, d);
618 case ICMD_I2L: /* ..., value ==> ..., value */
621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
622 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
624 emit_store_dst(jd, iptr, d);
628 case ICMD_L2I: /* ..., value ==> ..., value */
631 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
632 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
634 emit_store_dst(jd, iptr, d);
638 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
641 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
642 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
644 emit_store_dst(jd, iptr, d);
648 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
651 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
652 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
654 emit_store_dst(jd, iptr, d);
658 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
661 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
664 emit_store_dst(jd, iptr, d);
669 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
672 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
673 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
674 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
681 emit_store_dst(jd, iptr, d);
686 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
687 /* sx.val.i = constant */
690 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
691 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
693 /* Using inc and dec is not faster than add (tested with
697 M_IADD_IMM(iptr->sx.val.i, d);
698 emit_store_dst(jd, iptr, d);
702 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
705 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
706 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
707 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
714 emit_store_dst(jd, iptr, d);
718 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
719 /* sx.val.l = constant */
722 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
723 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
725 if (IS_IMM32(iptr->sx.val.l))
726 M_LADD_IMM(iptr->sx.val.l, d);
728 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
729 M_LADD(REG_ITMP2, d);
731 emit_store_dst(jd, iptr, d);
735 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
738 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
739 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
742 M_INTMOVE(s1, REG_ITMP1);
743 M_ISUB(s2, REG_ITMP1);
744 M_INTMOVE(REG_ITMP1, d);
749 emit_store_dst(jd, iptr, d);
753 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
754 /* sx.val.i = constant */
757 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
760 M_ISUB_IMM(iptr->sx.val.i, d);
761 emit_store_dst(jd, iptr, d);
765 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
768 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
769 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
770 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
772 M_INTMOVE(s1, REG_ITMP1);
773 M_LSUB(s2, REG_ITMP1);
774 M_INTMOVE(REG_ITMP1, d);
779 emit_store_dst(jd, iptr, d);
783 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
784 /* sx.val.l = constant */
787 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
788 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
790 if (IS_IMM32(iptr->sx.val.l))
791 M_LSUB_IMM(iptr->sx.val.l, d);
793 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
794 M_LSUB(REG_ITMP2, d);
796 emit_store_dst(jd, iptr, d);
800 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
803 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
804 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
805 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
812 emit_store_dst(jd, iptr, d);
816 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
817 /* sx.val.i = constant */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
822 if (iptr->sx.val.i == 2) {
826 M_IMUL_IMM(s1, iptr->sx.val.i, d);
827 emit_store_dst(jd, iptr, d);
831 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
834 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
835 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
836 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
843 emit_store_dst(jd, iptr, d);
847 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
848 /* sx.val.l = constant */
851 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
852 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
853 if (IS_IMM32(iptr->sx.val.l))
854 M_LMUL_IMM(s1, iptr->sx.val.l, d);
856 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
858 M_LMUL(REG_ITMP2, d);
860 emit_store_dst(jd, iptr, d);
864 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
867 var1 = VAROP(iptr->s1);
868 var2 = VAROP(iptr->sx.s23.s2);
869 dst = VAROP(iptr->dst);
871 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
872 if (IS_INMEMORY(var1->flags))
873 M_ILD(RAX, REG_SP, var1->vv.regoff * 8);
875 M_INTMOVE(var1->vv.regoff, RAX);
877 if (IS_INMEMORY(var2->flags))
878 M_ILD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
880 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
885 codegen_add_arithmeticexception_ref(cd);
888 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
889 emit_jcc(cd, CC_NE, 4 + 6);
890 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
891 emit_jcc(cd, CC_E, 3 + 1 + 3); /* 6 bytes */
893 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
895 emit_idivl_reg(cd, REG_ITMP3);
897 if (IS_INMEMORY(dst->flags)) {
898 emit_mov_reg_membase(cd, RAX, REG_SP, dst->vv.regoff * 8);
899 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
902 M_INTMOVE(RAX, dst->vv.regoff);
904 if (dst->vv.regoff != RDX) {
905 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
911 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
914 var1 = VAROP(iptr->s1);
915 var2 = VAROP(iptr->sx.s23.s2);
916 dst = VAROP(iptr->dst);
918 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
919 if (IS_INMEMORY(var1->flags))
920 M_ILD(RAX, REG_SP, var1->vv.regoff * 8);
922 M_INTMOVE(var1->vv.regoff, RAX);
924 if (IS_INMEMORY(var2->flags))
925 M_ILD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
927 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
932 codegen_add_arithmeticexception_ref(cd);
935 emit_mov_reg_reg(cd, RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
937 emit_alul_imm_reg(cd, ALU_CMP, 0x80000000, RAX); /* check as described in jvm spec */
938 emit_jcc(cd, CC_NE, 2 + 4 + 6);
941 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
942 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP3); /* 4 bytes */
943 emit_jcc(cd, CC_E, 1 + 3); /* 6 bytes */
946 emit_idivl_reg(cd, REG_ITMP3);
948 if (IS_INMEMORY(dst->flags)) {
949 emit_mov_reg_membase(cd, RDX, REG_SP, dst->vv.regoff * 8);
950 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
953 M_INTMOVE(RDX, dst->vv.regoff);
955 if (dst->vv.regoff != RDX) {
956 emit_mov_reg_reg(cd, REG_ITMP2, RDX); /* restore %rdx */
962 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
963 /* sx.val.i = constant */
966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
967 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
968 M_INTMOVE(s1, REG_ITMP1);
969 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
970 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
971 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
972 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
973 emit_mov_reg_reg(cd, REG_ITMP1, d);
974 emit_store_dst(jd, iptr, d);
978 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
979 /* sx.val.i = constant */
982 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
983 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
984 M_INTMOVE(s1, REG_ITMP1);
985 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
986 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
987 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
988 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
989 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
990 emit_mov_reg_reg(cd, REG_ITMP1, d);
991 emit_store_dst(jd, iptr, d);
996 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
999 var1 = VAROP(iptr->s1);
1000 var2 = VAROP(iptr->sx.s23.s2);
1001 dst = VAROP(iptr->dst);
1003 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1005 if (IS_INMEMORY(var1->flags))
1006 M_LLD(RAX, REG_SP, var1->vv.regoff * 8);
1008 M_INTMOVE(var1->vv.regoff, RAX);
1010 if (IS_INMEMORY(var2->flags))
1011 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
1013 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
1018 codegen_add_arithmeticexception_ref(cd);
1021 /* check as described in jvm spec */
1022 disp = dseg_add_s8(cd, 0x8000000000000000LL);
1023 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
1025 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
1026 M_BEQ(3 + 2 + 3); /* 6 bytes */
1028 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
1030 emit_idiv_reg(cd, REG_ITMP3);
1032 if (IS_INMEMORY(dst->flags)) {
1033 M_LST(RAX, REG_SP, dst->vv.regoff * 8);
1034 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1037 M_INTMOVE(RAX, dst->vv.regoff);
1039 if (dst->vv.regoff != RDX) {
1040 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1046 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1049 var1 = VAROP(iptr->s1);
1050 var2 = VAROP(iptr->sx.s23.s2);
1051 dst = VAROP(iptr->dst);
1053 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1055 if (IS_INMEMORY(var1->flags))
1056 M_LLD(REG_ITMP1, REG_SP, var1->vv.regoff * 8);
1058 M_INTMOVE(var1->vv.regoff, REG_ITMP1);
1060 if (IS_INMEMORY(var2->flags))
1061 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
1063 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
1065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1066 M_INTMOVE(s1, REG_ITMP1);
1067 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1068 M_INTMOVE(s2, REG_ITMP3);
1073 codegen_add_arithmeticexception_ref(cd);
1076 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
1078 /* check as described in jvm spec */
1079 disp = dseg_add_s8(cd, 0x8000000000000000LL);
1080 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
1084 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
1086 M_LXOR(RDX, RDX); /* 3 bytes */
1087 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
1088 M_BEQ(2 + 3); /* 6 bytes */
1091 emit_idiv_reg(cd, REG_ITMP3);
1093 if (IS_INMEMORY(dst->flags)) {
1094 M_LST(RDX, REG_SP, dst->vv.regoff * 8);
1095 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1098 M_INTMOVE(RDX, dst->vv.regoff);
1100 if (dst->vv.regoff != RDX) {
1101 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1107 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1108 /* sx.val.i = constant */
1111 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1112 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1113 M_INTMOVE(s1, REG_ITMP1);
1114 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1115 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
1116 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
1117 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
1118 emit_mov_reg_reg(cd, REG_ITMP1, d);
1119 emit_store_dst(jd, iptr, d);
1123 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1124 /* sx.val.l = constant */
1127 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1128 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1129 M_INTMOVE(s1, REG_ITMP1);
1130 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1131 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
1132 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
1133 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
1134 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
1135 emit_mov_reg_reg(cd, REG_ITMP1, d);
1136 emit_store_dst(jd, iptr, d);
1140 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1143 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1144 emit_ishift(jd, SHIFT_SHL, iptr);
1148 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1149 /* sx.val.i = constant */
1152 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1153 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1155 M_ISLL_IMM(iptr->sx.val.i, d);
1156 emit_store_dst(jd, iptr, d);
1160 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1163 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1164 emit_ishift(jd, SHIFT_SAR, iptr);
1168 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1169 /* sx.val.i = constant */
1172 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1173 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1175 M_ISRA_IMM(iptr->sx.val.i, d);
1176 emit_store_dst(jd, iptr, d);
1180 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1183 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1184 emit_ishift(jd, SHIFT_SHR, iptr);
1188 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1189 /* sx.val.i = constant */
1192 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1193 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1195 M_ISRL_IMM(iptr->sx.val.i, d);
1196 emit_store_dst(jd, iptr, d);
1200 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1203 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1204 emit_lshift(jd, SHIFT_SHL, iptr);
1208 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1209 /* sx.val.i = constant */
1212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1213 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1215 M_LSLL_IMM(iptr->sx.val.i, d);
1216 emit_store_dst(jd, iptr, d);
1220 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1223 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1224 emit_lshift(jd, SHIFT_SAR, iptr);
1228 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1229 /* sx.val.i = constant */
1232 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1233 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1235 M_LSRA_IMM(iptr->sx.val.i, d);
1236 emit_store_dst(jd, iptr, d);
1240 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1243 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1244 emit_lshift(jd, SHIFT_SHR, iptr);
1248 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1249 /* sx.val.l = constant */
1252 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1253 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1255 M_LSRL_IMM(iptr->sx.val.i, d);
1256 emit_store_dst(jd, iptr, d);
1260 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1263 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1264 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1265 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1272 emit_store_dst(jd, iptr, d);
1276 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1277 /* sx.val.i = constant */
1280 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1281 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1283 M_IAND_IMM(iptr->sx.val.i, d);
1284 emit_store_dst(jd, iptr, d);
1288 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1291 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1292 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1293 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1300 emit_store_dst(jd, iptr, d);
1304 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1305 /* sx.val.l = constant */
1308 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1309 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1311 if (IS_IMM32(iptr->sx.val.l))
1312 M_LAND_IMM(iptr->sx.val.l, d);
1314 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1315 M_LAND(REG_ITMP2, d);
1317 emit_store_dst(jd, iptr, d);
1321 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1324 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1325 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1326 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1333 emit_store_dst(jd, iptr, d);
1337 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1338 /* sx.val.i = constant */
1341 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1342 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1344 M_IOR_IMM(iptr->sx.val.i, d);
1345 emit_store_dst(jd, iptr, d);
1349 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1352 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1353 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1354 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1361 emit_store_dst(jd, iptr, d);
1365 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1366 /* sx.val.l = constant */
1369 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1370 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1372 if (IS_IMM32(iptr->sx.val.l))
1373 M_LOR_IMM(iptr->sx.val.l, d);
1375 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1376 M_LOR(REG_ITMP2, d);
1378 emit_store_dst(jd, iptr, d);
1382 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1385 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1386 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1387 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1394 emit_store_dst(jd, iptr, d);
1398 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1399 /* sx.val.i = constant */
1402 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1403 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1405 M_IXOR_IMM(iptr->sx.val.i, d);
1406 emit_store_dst(jd, iptr, d);
1410 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1413 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1415 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1422 emit_store_dst(jd, iptr, d);
1426 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1427 /* sx.val.l = constant */
1430 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1431 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1433 if (IS_IMM32(iptr->sx.val.l))
1434 M_LXOR_IMM(iptr->sx.val.l, d);
1436 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1437 M_LXOR(REG_ITMP2, d);
1439 emit_store_dst(jd, iptr, d);
1444 /* floating operations ************************************************/
1446 case ICMD_FNEG: /* ..., value ==> ..., - value */
1449 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1450 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1451 disp = dseg_add_s4(cd, 0x80000000);
1453 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1454 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1455 emit_store_dst(jd, iptr, d);
1459 case ICMD_DNEG: /* ..., value ==> ..., - value */
1462 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1464 disp = dseg_add_s8(cd, 0x8000000000000000);
1466 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1467 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1468 emit_store_dst(jd, iptr, d);
1472 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1475 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1476 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1477 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1484 emit_store_dst(jd, iptr, d);
1488 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1491 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1492 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1493 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1500 emit_store_dst(jd, iptr, d);
1504 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1507 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1508 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1509 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1511 M_FLTMOVE(s2, REG_FTMP2);
1516 emit_store_dst(jd, iptr, d);
1520 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1523 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1524 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1525 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1527 M_FLTMOVE(s2, REG_FTMP2);
1532 emit_store_dst(jd, iptr, d);
1536 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1539 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1540 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1541 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1548 emit_store_dst(jd, iptr, d);
1552 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1555 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1556 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1557 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1564 emit_store_dst(jd, iptr, d);
1568 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1571 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1572 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1573 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1575 M_FLTMOVE(s2, REG_FTMP2);
1580 emit_store_dst(jd, iptr, d);
1584 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1587 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1588 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1589 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1591 M_FLTMOVE(s2, REG_FTMP2);
1596 emit_store_dst(jd, iptr, d);
1600 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1603 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1604 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1606 emit_store_dst(jd, iptr, d);
1610 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1613 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1614 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1616 emit_store_dst(jd, iptr, d);
1620 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1623 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1624 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1626 emit_store_dst(jd, iptr, d);
1630 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1633 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1634 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1636 emit_store_dst(jd, iptr, d);
1640 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1643 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1644 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1646 M_ICMP_IMM(0x80000000, d); /* corner cases */
1647 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1648 ((REG_RESULT == d) ? 0 : 3);
1650 M_FLTMOVE(s1, REG_FTMP1);
1651 M_MOV_IMM(asm_builtin_f2i, REG_ITMP2);
1653 M_INTMOVE(REG_RESULT, d);
1654 emit_store_dst(jd, iptr, d);
1658 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1661 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1662 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1664 M_ICMP_IMM(0x80000000, d); /* corner cases */
1665 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1666 ((REG_RESULT == d) ? 0 : 3);
1668 M_FLTMOVE(s1, REG_FTMP1);
1669 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1671 M_INTMOVE(REG_RESULT, d);
1672 emit_store_dst(jd, iptr, d);
1676 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1679 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1680 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1682 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1683 M_LCMP(REG_ITMP2, d); /* corner cases */
1684 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1685 ((REG_RESULT == d) ? 0 : 3);
1687 M_FLTMOVE(s1, REG_FTMP1);
1688 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1690 M_INTMOVE(REG_RESULT, d);
1691 emit_store_dst(jd, iptr, d);
1695 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1698 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1699 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1701 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1702 M_LCMP(REG_ITMP2, d); /* corner cases */
1703 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1704 ((REG_RESULT == d) ? 0 : 3);
1706 M_FLTMOVE(s1, REG_FTMP1);
1707 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1709 M_INTMOVE(REG_RESULT, d);
1710 emit_store_dst(jd, iptr, d);
1714 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1717 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1718 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1720 emit_store_dst(jd, iptr, d);
1724 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1727 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1728 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1730 emit_store_dst(jd, iptr, d);
1734 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1735 /* == => 0, < => 1, > => -1 */
1738 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1739 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1740 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1742 M_MOV_IMM(1, REG_ITMP1);
1743 M_MOV_IMM(-1, REG_ITMP2);
1744 emit_ucomiss_reg_reg(cd, s1, s2);
1745 M_CMOVB(REG_ITMP1, d);
1746 M_CMOVA(REG_ITMP2, d);
1747 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1748 emit_store_dst(jd, iptr, d);
1752 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1753 /* == => 0, < => 1, > => -1 */
1756 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1757 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1758 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1760 M_MOV_IMM(1, REG_ITMP1);
1761 M_MOV_IMM(-1, REG_ITMP2);
1762 emit_ucomiss_reg_reg(cd, s1, s2);
1763 M_CMOVB(REG_ITMP1, d);
1764 M_CMOVA(REG_ITMP2, d);
1765 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1766 emit_store_dst(jd, iptr, d);
1770 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1771 /* == => 0, < => 1, > => -1 */
1774 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1775 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1776 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1778 M_MOV_IMM(1, REG_ITMP1);
1779 M_MOV_IMM(-1, REG_ITMP2);
1780 emit_ucomisd_reg_reg(cd, s1, s2);
1781 M_CMOVB(REG_ITMP1, d);
1782 M_CMOVA(REG_ITMP2, d);
1783 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1784 emit_store_dst(jd, iptr, d);
1788 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1789 /* == => 0, < => 1, > => -1 */
1792 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1793 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1794 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1796 M_MOV_IMM(1, REG_ITMP1);
1797 M_MOV_IMM(-1, REG_ITMP2);
1798 emit_ucomisd_reg_reg(cd, s1, s2);
1799 M_CMOVB(REG_ITMP1, d);
1800 M_CMOVA(REG_ITMP2, d);
1801 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1802 emit_store_dst(jd, iptr, d);
1807 /* memory operations **************************************************/
1809 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1812 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1813 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1814 gen_nullptr_check(s1);
1815 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1816 emit_store_dst(jd, iptr, d);
1820 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1823 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1824 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1825 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1826 if (INSTRUCTION_MUST_CHECK(iptr)) {
1827 gen_nullptr_check(s1);
1830 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1831 emit_store_dst(jd, iptr, d);
1835 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1839 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1841 if (INSTRUCTION_MUST_CHECK(iptr)) {
1842 gen_nullptr_check(s1);
1845 emit_movzwq_memindex_reg(cd, OFFSET(java_chararray, data[0]), s1, s2, 1, d);
1846 emit_store_dst(jd, iptr, d);
1850 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1853 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1854 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1855 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1856 if (INSTRUCTION_MUST_CHECK(iptr)) {
1857 gen_nullptr_check(s1);
1860 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1861 emit_store_dst(jd, iptr, d);
1865 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1868 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1869 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1870 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1871 if (INSTRUCTION_MUST_CHECK(iptr)) {
1872 gen_nullptr_check(s1);
1875 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1876 emit_store_dst(jd, iptr, d);
1880 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1883 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1884 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1885 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1886 if (INSTRUCTION_MUST_CHECK(iptr)) {
1887 gen_nullptr_check(s1);
1890 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1891 emit_store_dst(jd, iptr, d);
1895 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1898 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1899 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1900 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1901 if (INSTRUCTION_MUST_CHECK(iptr)) {
1902 gen_nullptr_check(s1);
1905 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1906 emit_store_dst(jd, iptr, d);
1910 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1913 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1914 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1915 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1916 if (INSTRUCTION_MUST_CHECK(iptr)) {
1917 gen_nullptr_check(s1);
1920 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1921 emit_store_dst(jd, iptr, d);
1925 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1926 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1927 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1928 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1929 emit_array_checks(cd, iptr, s1, s2);
1930 M_SAADDQ(s2, s1, REG_ITMP1);
1931 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1932 emit_store_dst(jd, iptr, d);
1935 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1938 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1939 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1940 if (INSTRUCTION_MUST_CHECK(iptr)) {
1941 gen_nullptr_check(s1);
1944 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1945 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1949 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1952 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1953 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1954 if (INSTRUCTION_MUST_CHECK(iptr)) {
1955 gen_nullptr_check(s1);
1958 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1959 emit_movw_reg_memindex(cd, s3, OFFSET(java_chararray, data[0]), s1, s2, 1);
1963 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1967 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1968 if (INSTRUCTION_MUST_CHECK(iptr)) {
1969 gen_nullptr_check(s1);
1972 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1973 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1977 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1980 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1981 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1982 if (INSTRUCTION_MUST_CHECK(iptr)) {
1983 gen_nullptr_check(s1);
1986 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1987 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1991 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1994 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1995 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1996 if (INSTRUCTION_MUST_CHECK(iptr)) {
1997 gen_nullptr_check(s1);
2000 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2001 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
2005 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
2008 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2009 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2010 if (INSTRUCTION_MUST_CHECK(iptr)) {
2011 gen_nullptr_check(s1);
2014 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
2015 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
2019 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
2022 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2023 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2024 if (INSTRUCTION_MUST_CHECK(iptr)) {
2025 gen_nullptr_check(s1);
2028 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
2029 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
2033 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
2036 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2037 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2038 if (INSTRUCTION_MUST_CHECK(iptr)) {
2039 gen_nullptr_check(s1);
2042 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2046 M_MOV_IMM(BUILTIN_canstore, REG_ITMP1);
2050 codegen_add_arraystoreexception_ref(cd);
2052 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2053 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2054 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
2055 emit_mov_reg_memindex(cd, s3, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2060 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
2063 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2064 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2065 if (INSTRUCTION_MUST_CHECK(iptr)) {
2066 gen_nullptr_check(s1);
2069 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
2073 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2076 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2077 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2078 if (INSTRUCTION_MUST_CHECK(iptr)) {
2079 gen_nullptr_check(s1);
2082 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
2086 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2089 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2090 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2091 if (INSTRUCTION_MUST_CHECK(iptr)) {
2092 gen_nullptr_check(s1);
2095 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2099 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2102 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2103 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2104 if (INSTRUCTION_MUST_CHECK(iptr)) {
2105 gen_nullptr_check(s1);
2108 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
2112 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
2115 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2116 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2117 if (INSTRUCTION_MUST_CHECK(iptr)) {
2118 gen_nullptr_check(s1);
2122 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
2123 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2125 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2126 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2131 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2134 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2135 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2136 if (INSTRUCTION_MUST_CHECK(iptr)) {
2137 gen_nullptr_check(s1);
2140 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2145 case ICMD_GETSTATIC: /* ... ==> ..., value */
2147 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2148 uf = iptr->sx.s23.s3.uf;
2149 fieldtype = uf->fieldref->parseddesc.fd->type;
2150 disp = dseg_add_unique_address(cd, NULL);
2152 /* PROFILE_CYCLE_STOP; */
2154 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2156 /* PROFILE_CYCLE_START; */
2159 fi = iptr->sx.s23.s3.fmiref->p.field;
2160 fieldtype = fi->type;
2161 disp = dseg_add_address(cd, &(fi->value));
2163 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2166 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
2168 PROFILE_CYCLE_START;
2172 M_ALD(REG_ITMP1, REG_PV, disp);
2174 switch (fieldtype) {
2176 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2177 M_ILD(d, REG_ITMP1, 0);
2180 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2181 M_LLD(d, REG_ITMP1, 0);
2184 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2185 M_ALD(d, REG_ITMP1, 0);
2188 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2189 M_FLD(d, REG_ITMP1, 0);
2192 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2193 M_DLD(d, REG_ITMP1, 0);
2197 emit_store_dst(jd, iptr, d);
2201 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2203 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2204 uf = iptr->sx.s23.s3.uf;
2205 fieldtype = uf->fieldref->parseddesc.fd->type;
2206 disp = dseg_add_unique_address(cd, uf);
2208 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2211 fi = iptr->sx.s23.s3.fmiref->p.field;
2212 fieldtype = fi->type;
2213 disp = dseg_add_address(cd, &(fi->value));
2215 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2216 codegen_addpatchref(cd, PATCHER_clinit,
2220 M_ALD(REG_ITMP1, REG_PV, disp);
2221 switch (fieldtype) {
2223 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2224 M_IST(s1, REG_ITMP1, 0);
2227 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2228 M_LST(s1, REG_ITMP1, 0);
2231 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2232 M_AST(s1, REG_ITMP1, 0);
2235 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2236 M_FST(s1, REG_ITMP1, 0);
2239 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2240 M_DST(s1, REG_ITMP1, 0);
2245 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2246 /* val = value (in current instruction) */
2247 /* following NOP) */
2250 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2251 uf = iptr->sx.s23.s3.uf;
2252 fieldtype = uf->fieldref->parseddesc.fd->type;
2253 disp = dseg_add_unique_address(cd, NULL);
2254 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2256 /* must be calculated before codegen_add_patch_ref */
2259 disp -= PATCHER_CALL_SIZE;
2262 /* PROFILE_CYCLE_STOP; */
2264 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2266 /* PROFILE_CYCLE_START; */
2269 fi = iptr->sx.s23.s3.fmiref->p.field;
2270 fieldtype = fi->type;
2271 disp = dseg_add_address(cd, &(fi->value));
2272 disp = -((cd->mcodeptr + 7) - cd->mcodebase) + disp;
2274 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2277 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
2280 disp -= PATCHER_CALL_SIZE;
2282 PROFILE_CYCLE_START;
2286 /* This approach is much faster than moving the field
2287 address inline into a register. */
2289 M_ALD(REG_ITMP1, RIP, disp);
2291 switch (fieldtype) {
2294 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2299 if (IS_IMM32(iptr->sx.s23.s2.constval))
2300 M_LST_IMM32(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2302 M_IST_IMM(iptr->sx.s23.s2.constval, REG_ITMP1, 0);
2303 M_IST_IMM(iptr->sx.s23.s2.constval >> 32, REG_ITMP1, 4);
2310 case ICMD_GETFIELD: /* ... ==> ..., value */
2313 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2314 gen_nullptr_check(s1);
2316 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2317 uf = iptr->sx.s23.s3.uf;
2318 fieldtype = uf->fieldref->parseddesc.fd->type;
2321 /* PROFILE_CYCLE_STOP; */
2323 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2325 /* PROFILE_CYCLE_START; */
2328 fi = iptr->sx.s23.s3.fmiref->p.field;
2329 fieldtype = fi->type;
2333 switch (fieldtype) {
2335 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2336 M_ILD32(d, s1, disp);
2340 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
2341 M_LLD32(d, s1, disp);
2344 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2345 M_FLD32(d, s1, disp);
2348 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2349 M_DLD32(d, s1, disp);
2352 emit_store_dst(jd, iptr, d);
2356 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2359 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2360 gen_nullptr_check(s1);
2362 s2 = emit_load_s2(jd, iptr, REG_IFTMP);
2364 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2365 uf = iptr->sx.s23.s3.uf;
2366 fieldtype = uf->fieldref->parseddesc.fd->type;
2369 /* PROFILE_CYCLE_STOP; */
2371 codegen_add_patch_ref(cd, PATCHER_get_putfield, uf, 0);
2373 /* PROFILE_CYCLE_START; */
2376 fi = iptr->sx.s23.s3.fmiref->p.field;
2377 fieldtype = fi->type;
2381 switch (fieldtype) {
2383 M_IST32(s2, s1, disp);
2387 M_LST32(s2, s1, disp);
2390 M_FST32(s2, s1, disp);
2393 M_DST32(s2, s1, disp);
2399 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2400 /* val = value (in current instruction) */
2401 /* following NOP) */
2404 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2405 gen_nullptr_check(s1);
2407 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2408 uf = iptr->sx.s23.s3.uf;
2409 fieldtype = uf->fieldref->parseddesc.fd->type;
2412 /* PROFILE_CYCLE_STOP; */
2414 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2416 /* PROFILE_CYCLE_START; */
2419 fi = iptr->sx.s23.s3.fmiref->p.field;
2420 fieldtype = fi->type;
2424 switch (fieldtype) {
2427 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2432 /* XXX why no check for IS_IMM32? */
2433 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2434 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2441 /* branch operations **************************************************/
2443 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2446 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2447 M_INTMOVE(s1, REG_ITMP1_XPTR);
2451 #ifdef ENABLE_VERIFIER
2452 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2453 uc = iptr->sx.s23.s2.uc;
2455 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2457 #endif /* ENABLE_VERIFIER */
2459 M_CALL_IMM(0); /* passing exception pc */
2460 M_POP(REG_ITMP2_XPC);
2462 M_MOV_IMM(asm_handle_exception, REG_ITMP3);
2467 case ICMD_GOTO: /* ... ==> ... */
2468 case ICMD_RET: /* ... ==> ... */
2471 codegen_add_branch_ref(cd, iptr->dst.block);
2475 case ICMD_JSR: /* ... ==> ... */
2479 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2483 case ICMD_IFNULL: /* ..., value ==> ... */
2484 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2487 codegen_add_branch_ref(cd, iptr->dst.block);
2490 case ICMD_IFNONNULL: /* ..., value ==> ... */
2491 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2494 codegen_add_branch_ref(cd, iptr->dst.block);
2497 case ICMD_IFEQ: /* ..., value ==> ... */
2498 case ICMD_IFLT: /* ..., value ==> ... */
2499 case ICMD_IFLE: /* ..., value ==> ... */
2500 case ICMD_IFNE: /* ..., value ==> ... */
2501 case ICMD_IFGT: /* ..., value ==> ... */
2502 case ICMD_IFGE: /* ..., value ==> ... */
2504 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2506 if ((iptr->sx.val.i >= -32768) && (iptr->sx.val.i <= 32767))
2507 N_CHI(s1, iptr->sx.val.i);
2509 disp = dseg_add_s4(cd, iptr->sx.val.i);
2510 N_LHI(REG_ITMP2, disp);
2511 N_CL(s1, 0, REG_ITMP2, REG_PV);
2514 switch (iptr->opc) {
2534 codegen_add_branch_ref(cd, iptr->dst.block);
2538 case ICMD_IF_LEQ: /* ..., value ==> ... */
2541 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2542 if (IS_IMM32(iptr->sx.val.l))
2543 M_LCMP_IMM(iptr->sx.val.l, s1);
2545 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2546 M_LCMP(REG_ITMP2, s1);
2549 codegen_add_branch_ref(cd, iptr->dst.block);
2553 case ICMD_IF_LLT: /* ..., value ==> ... */
2557 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2558 if (IS_IMM32(iptr->sx.val.l))
2559 M_LCMP_IMM(iptr->sx.val.l, s1);
2561 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2562 M_LCMP(REG_ITMP2, s1);
2565 codegen_add_branch_ref(cd, iptr->dst.block);
2569 case ICMD_IF_LLE: /* ..., value ==> ... */
2573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2574 if (IS_IMM32(iptr->sx.val.l))
2575 M_LCMP_IMM(iptr->sx.val.l, s1);
2577 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2578 M_LCMP(REG_ITMP2, s1);
2581 codegen_add_branch_ref(cd, iptr->dst.block);
2585 case ICMD_IF_LNE: /* ..., value ==> ... */
2589 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2590 if (IS_IMM32(iptr->sx.val.l))
2591 M_LCMP_IMM(iptr->sx.val.l, s1);
2593 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2594 M_LCMP(REG_ITMP2, s1);
2597 codegen_add_branch_ref(cd, iptr->dst.block);
2601 case ICMD_IF_LGT: /* ..., value ==> ... */
2605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2606 if (IS_IMM32(iptr->sx.val.l))
2607 M_LCMP_IMM(iptr->sx.val.l, s1);
2609 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2610 M_LCMP(REG_ITMP2, s1);
2613 codegen_add_branch_ref(cd, iptr->dst.block);
2617 case ICMD_IF_LGE: /* ..., value ==> ... */
2621 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2622 if (IS_IMM32(iptr->sx.val.l))
2623 M_LCMP_IMM(iptr->sx.val.l, s1);
2625 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2626 M_LCMP(REG_ITMP2, s1);
2629 codegen_add_branch_ref(cd, iptr->dst.block);
2633 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2634 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2637 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2640 codegen_add_branch_ref(cd, iptr->dst.block);
2643 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2645 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2646 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2648 /* load low-bits before the branch, so we know the distance */
2649 /* TODO do the loads modify the condition code?
2650 * lr, l, la, lhi dont
2652 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2653 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2654 M_BNE(SZ_BRC + SZ_CR + SZ_BRC);
2657 codegen_add_branch_ref(cd, iptr->dst.block);
2660 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2664 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2665 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2668 codegen_add_branch_ref(cd, iptr->dst.block);
2672 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2673 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2677 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2678 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2681 codegen_add_branch_ref(cd, iptr->dst.block);
2685 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2689 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2690 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2693 codegen_add_branch_ref(cd, iptr->dst.block);
2697 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2701 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2702 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2705 codegen_add_branch_ref(cd, iptr->dst.block);
2709 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2713 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2714 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2717 codegen_add_branch_ref(cd, iptr->dst.block);
2721 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2726 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2729 codegen_add_branch_ref(cd, iptr->dst.block);
2733 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2737 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2738 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2741 codegen_add_branch_ref(cd, iptr->dst.block);
2745 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2747 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2748 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2751 codegen_add_branch_ref(cd, iptr->dst.block);
2752 /* load low-bits before the branch, so we know the distance */
2753 /* TODO: the loads should not touch the condition code. */
2754 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2755 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2756 M_BGT(SZ_BRC + SZ_CR + SZ_BRC);
2759 codegen_add_branch_ref(cd, iptr->dst.block);
2762 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2766 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2767 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2770 codegen_add_branch_ref(cd, iptr->dst.block);
2774 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2778 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2779 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2782 codegen_add_branch_ref(cd, iptr->dst.block);
2786 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2788 REPLACEMENT_POINT_RETURN(cd, iptr);
2789 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2790 M_INTMOVE(s1, REG_RESULT);
2791 goto nowperformreturn;
2793 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2795 REPLACEMENT_POINT_RETURN(cd, iptr);
2796 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2797 M_INTMOVE(s1, REG_RESULT);
2799 #ifdef ENABLE_VERIFIER
2800 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2801 unresolved_class *uc = iptr->sx.s23.s2.uc;
2803 codegen_addpatchref(cd, PATCHER_athrow_areturn, uc, 0);
2805 #endif /* ENABLE_VERIFIER */
2806 goto nowperformreturn;
2808 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2810 REPLACEMENT_POINT_RETURN(cd, iptr);
2811 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2812 M_LNGMOVE(s1, REG_RESULT_PACKED);
2813 goto nowperformreturn;
2815 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2818 REPLACEMENT_POINT_RETURN(cd, iptr);
2819 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2820 M_FLTMOVE(s1, REG_FRESULT);
2821 goto nowperformreturn;
2823 case ICMD_RETURN: /* ... ==> ... */
2825 REPLACEMENT_POINT_RETURN(cd, iptr);
2831 p = cd->stackframesize;
2833 /* call trace function */
2835 emit_verbosecall_exit(jd);
2837 #if defined(ENABLE_THREADS)
2838 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2839 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2840 M_ALD(REG_ITMP3, REG_PV, disp);
2843 /* we need to save the proper return value */
2845 switch (iptr->opc) {
2847 M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2851 M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2854 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2857 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2861 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
2864 /* and now restore the proper return value */
2866 switch (iptr->opc) {
2868 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2872 M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2875 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2878 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2884 /* restore return address */
2886 M_ALD(REG_RA, REG_SP, p * 4);
2888 /* restore saved registers */
2890 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2891 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2893 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2894 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2897 /* deallocate stack */
2899 if (cd->stackframesize)
2900 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2907 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2912 branch_target_t *table;
2914 table = iptr->dst.table;
2916 l = iptr->sx.s23.s2.tablelow;
2917 i = iptr->sx.s23.s3.tablehigh;
2919 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2920 M_INTMOVE(s1, REG_ITMP1);
2923 M_ISUB_IMM(l, REG_ITMP1);
2925 /* number of targets */
2929 M_ICMP_IMM(i - 1, REG_ITMP1);
2932 codegen_add_branch_ref(cd, table[0].block); /* default target */
2934 /* build jump table top down and use address of lowest entry */
2939 dseg_add_target(cd, table->block);
2943 /* length of dataseg after last dseg_add_target is used
2946 M_MOV_IMM(0, REG_ITMP2);
2948 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2955 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2960 lookup_target_t *lookup;
2962 lookup = iptr->dst.lookup;
2964 i = iptr->sx.s23.s2.lookupcount;
2966 MCODECHECK(8 + ((7 + 6) * i) + 5);
2967 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2970 M_ICMP_IMM(lookup->value, s1);
2972 codegen_add_branch_ref(cd, lookup->target.block);
2978 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2984 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2986 bte = iptr->sx.s23.s3.bte;
2990 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2991 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2992 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2993 case ICMD_INVOKEINTERFACE:
2995 REPLACEMENT_POINT_INVOKE(cd, iptr);
2997 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2999 um = iptr->sx.s23.s3.um;
3000 md = um->methodref->parseddesc.md;
3003 lm = iptr->sx.s23.s3.fmiref->p.method;
3005 md = lm->parseddesc;
3009 s3 = md->paramcount;
3011 MCODECHECK((s3 << 1) + 64);
3013 /* copy arguments to registers or stack location */
3015 for (s3 = s3 - 1; s3 >= 0; s3--) {
3016 var = VAR(iptr->sx.s23.s2.args[s3]);
3018 /* Already Preallocated? */
3019 if (var->flags & PREALLOC)
3022 if (IS_INT_LNG_TYPE(var->type)) {
3023 if (!md->params[s3].inmemory) {
3024 if (IS_2_WORD_TYPE(var->type)) {
3026 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
3027 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]
3029 d = emit_load(jd, iptr, var, s1);
3033 s1 = rd->argintregs[md->params[s3].regoff];
3034 d = emit_load(jd, iptr, var, s1);
3039 if (IS_2_WORD_TYPE(var->type)) {
3040 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
3041 M_LST(d, REG_SP, md->params[s3].regoff * 4);
3044 d = emit_load(jd, iptr, var, REG_ITMP1);
3045 M_IST(d, REG_SP, md->params[s3].regoff * 4);
3050 if (!md->params[s3].inmemory) {
3051 s1 = rd->argfltregs[md->params[s3].regoff];
3052 d = emit_load(jd, iptr, var, s1);
3056 d = emit_load(jd, iptr, var, REG_FTMP1);
3057 if (IS_2_WORD_TYPE(var->type))
3058 M_DST(d, REG_SP, md->params[s3].regoff * 4);
3060 M_FST(d, REG_SP, md->params[s3].regoff * 4);
3065 switch (iptr->opc) {
3067 disp = dseg_add_functionptr(cd, bte->fp);
3069 N_LHI(REG_ITMP1, disp);
3070 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3073 case ICMD_INVOKESPECIAL:
3074 emit_nullpointer_check(cd, iptr, REG_A0);
3075 M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr */
3078 case ICMD_INVOKESTATIC:
3080 disp = dseg_add_unique_address(cd, um);
3082 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3086 disp = dseg_add_address(cd, lm->stubroutine);
3088 N_LHI(REG_ITMP1, disp);
3089 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3092 case ICMD_INVOKEVIRTUAL:
3093 emit_nullpointer_check(cd, iptr, REG_A0);
3096 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3101 s1 = OFFSET(vftbl_t, table[0]) +
3102 sizeof(methodptr) * lm->vftblindex;
3105 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3106 M_ALD(REG_PV, REG_METHODPTR, s1);
3109 case ICMD_INVOKEINTERFACE:
3110 emit_nullpointer_check(cd, iptr, REG_A0);
3113 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3119 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3120 sizeof(methodptr*) * lm->class->index;
3122 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3125 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3126 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3127 M_ALD(REG_PV, REG_METHODPTR, s2);
3131 /* generate the actual call */
3134 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3135 N_BASR(REG_ITMP1, RN);
3136 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3137 M_LDA(REG_PV, REG_ITMP1, -disp);
3139 /* actually only used for ICMD_BUILTIN */
3141 if (INSTRUCTION_MUST_CHECK(iptr)) {
3144 codegen_add_fillinstacktrace_ref(cd);
3147 /* store return value */
3149 d = md->returntype.type;
3151 if (d != TYPE_VOID) {
3152 if (IS_INT_LNG_TYPE(d)) {
3153 if (IS_2_WORD_TYPE(d)) {
3154 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3155 M_LNGMOVE(REG_RESULT_PACKED, s1);
3158 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3159 M_INTMOVE(REG_RESULT, s1);
3163 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3164 M_FLTMOVE(REG_FRESULT, s1);
3166 emit_store_dst(jd, iptr, s1);
3172 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3176 /* val.a: (classinfo *) superclass */
3178 /* superclass is an interface:
3180 * OK if ((sub == NULL) ||
3181 * (sub->vftbl->interfacetablelength > super->index) &&
3182 * (sub->vftbl->interfacetable[-super->index] != NULL));
3184 * superclass is a class:
3186 * OK if ((sub == NULL) || (0
3187 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3188 * super->vftbl->diffval));
3191 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3192 /* object type cast-check */
3195 vftbl_t *supervftbl;
3198 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3204 super = iptr->sx.s23.s3.c.cls;
3205 superindex = super->index;
3206 supervftbl = super->vftbl;
3209 #if defined(ENABLE_THREADS)
3210 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3212 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3214 /* calculate interface checkcast code size */
3216 s2 = 3; /* mov_membase_reg */
3217 CALCOFFSETBYTES(s2, s1, OFFSET(java_objectheader, vftbl));
3219 s2 += 3 + 4 /* movl_membase32_reg */ + 3 + 4 /* sub imm32 */ +
3220 3 /* test */ + 6 /* jcc */ + 3 + 4 /* mov_membase32_reg */ +
3221 3 /* test */ + 6 /* jcc */;
3224 s2 += (opt_shownops ? 5 : 0);
3226 /* calculate class checkcast code size */
3228 s3 = 3; /* mov_membase_reg */
3229 CALCOFFSETBYTES(s3, s1, OFFSET(java_objectheader, vftbl));
3230 s3 += 10 /* mov_imm_reg */ + 3 + 4 /* movl_membase32_reg */;
3233 if (s1 != REG_ITMP1) {
3234 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
3235 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, baseval));
3236 a += 3; /* movl_membase_reg - only if REG_ITMP3 == R11 */
3237 CALCOFFSETBYTES(a, REG_ITMP3, OFFSET(vftbl_t, diffval));
3243 s3 += 3 + 4 /* movl_membase32_reg */ + 3 /* sub */ +
3244 10 /* mov_imm_reg */ + 3 /* movl_membase_reg */;
3245 CALCOFFSETBYTES(s3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3248 s3 += 3 /* cmp */ + 6 /* jcc */;
3251 s3 += (opt_shownops ? 5 : 0);
3253 /* if class is not resolved, check which code to call */
3255 if (super == NULL) {
3257 M_BEQ(6 + (opt_shownops ? 5 : 0) + 7 + 6 + s2 + 5 + s3);
3259 codegen_add_patch_ref(cd, PATCHER_checkcast_instanceof_flags,
3260 iptr->sx.s23.s3.c.ref, 0);
3262 M_IMOV_IMM(0, REG_ITMP2); /* super->flags */
3263 M_IAND_IMM(ACC_INTERFACE, REG_ITMP2);
3267 /* interface checkcast code */
3269 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3270 if (super != NULL) {
3275 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3277 if (super == NULL) {
3278 codegen_add_patch_ref(cd,
3279 PATCHER_checkcast_instanceof_interface,
3280 iptr->sx.s23.s3.c.ref,
3284 emit_movl_membase32_reg(cd, REG_ITMP2,
3285 OFFSET(vftbl_t, interfacetablelength),
3287 /* XXX TWISTI: should this be int arithmetic? */
3288 M_LSUB_IMM32(superindex, REG_ITMP3);
3291 codegen_add_classcastexception_ref(cd, s1);
3292 emit_mov_membase32_reg(cd, REG_ITMP2,
3293 OFFSET(vftbl_t, interfacetable[0]) -
3294 superindex * sizeof(methodptr*),
3298 codegen_add_classcastexception_ref(cd, s1);
3304 /* class checkcast code */
3306 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3307 if (super != NULL) {
3312 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3314 if (super == NULL) {
3315 codegen_add_patch_ref(cd, PATCHER_checkcast_class,
3316 iptr->sx.s23.s3.c.ref,
3320 M_MOV_IMM(supervftbl, REG_ITMP3);
3321 #if defined(ENABLE_THREADS)
3322 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3324 emit_movl_membase32_reg(cd, REG_ITMP2,
3325 OFFSET(vftbl_t, baseval),
3327 /* if (s1 != REG_ITMP1) { */
3328 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3329 /* OFFSET(vftbl_t, baseval), */
3331 /* emit_movl_membase_reg(cd, REG_ITMP3, */
3332 /* OFFSET(vftbl_t, diffval), */
3334 /* #if defined(ENABLE_THREADS) */
3335 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3337 /* emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP1, REG_ITMP2); */
3340 emit_movl_membase32_reg(cd, REG_ITMP3,
3341 OFFSET(vftbl_t, baseval),
3343 M_LSUB(REG_ITMP3, REG_ITMP2);
3344 M_MOV_IMM(supervftbl, REG_ITMP3);
3345 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3347 #if defined(ENABLE_THREADS)
3348 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3350 M_LCMP(REG_ITMP3, REG_ITMP2);
3351 M_BA(0); /* (u) REG_ITMP1 > (u) REG_ITMP2 -> jump */
3352 codegen_add_classcastexception_ref(cd, s1);
3355 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
3358 /* array type cast-check */
3360 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3361 M_INTMOVE(s1, REG_A0);
3363 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3364 codegen_add_patch_ref(cd, PATCHER_builtin_arraycheckcast,
3365 iptr->sx.s23.s3.c.ref, 0);
3368 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3369 M_MOV_IMM(BUILTIN_arraycheckcast, REG_ITMP1);
3372 /* s1 may have been destroyed over the function call */
3373 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
3376 codegen_add_classcastexception_ref(cd, s1);
3378 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3382 emit_store_dst(jd, iptr, d);
3386 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3389 /* val.a: (classinfo*) superclass */
3391 /* superclass is an interface:
3393 * return (sub != NULL) &&
3394 * (sub->vftbl->interfacetablelength > super->index) &&
3395 * (sub->vftbl->interfacetable[-super->index] != NULL);
3397 * superclass is a class:
3399 * return ((sub != NULL) && (0
3400 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3401 * super->vftbl->diffvall));
3406 vftbl_t *supervftbl;
3409 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3415 super = iptr->sx.s23.s3.c.cls;
3416 superindex = super->index;
3417 supervftbl = super->vftbl;
3420 #if defined(ENABLE_THREADS)
3421 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3423 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3424 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3426 M_MOV(s1, REG_ITMP1);
3430 /* calculate interface instanceof code size */
3434 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_shownops ? 1 : 0);
3436 /* calculate class instanceof code size */
3440 s3 += (opt_shownops ? 1 : 0);
3442 /* if class is not resolved, check which code to call */
3444 if (super == NULL) {
3446 M_BEQZ(s1, 4 + (opt_shownops ? 1 : 0) + s2 + 1 + s3);
3448 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3450 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
3451 iptr->sx.s23.s3.c.ref, disp);
3453 M_ILD(REG_ITMP3, REG_PV, disp);
3455 disp = dseg_add_s4(cd, ACC_INTERFACE);
3456 M_ILD(REG_ITMP2, REG_PV, disp);
3457 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3458 M_BEQZ(REG_ITMP3, s2 + 1);
3461 /* interface instanceof code */
3463 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3464 if (super == NULL) {
3465 /* If d == REG_ITMP2, then it's destroyed in check
3470 codegen_add_patch_ref(cd,
3471 PATCHER_checkcast_instanceof_interface,
3472 iptr->sx.s23.s3.c.ref, 0);
3479 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3480 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3481 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3482 M_BLEZ(REG_ITMP3, 2);
3483 M_ALD(REG_ITMP1, REG_ITMP1,
3484 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3485 superindex * sizeof(methodptr*)));
3486 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3492 /* class instanceof code */
3494 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3495 if (super == NULL) {
3496 disp = dseg_add_unique_address(cd, NULL);
3498 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3499 iptr->sx.s23.s3.c.ref,
3503 disp = dseg_add_address(cd, supervftbl);
3509 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3510 M_ALD(REG_ITMP2, REG_PV, disp);
3511 #if defined(ENABLE_THREADS)
3512 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3514 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3515 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3516 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3517 #if defined(ENABLE_THREADS)
3518 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3520 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3521 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3523 emit_store_dst(jd, iptr, d);
3528 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3532 /* check for negative sizes and copy sizes to stack if necessary */
3534 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3536 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3538 /* copy SAVEDVAR sizes to stack */
3539 var = VAR(iptr->sx.s23.s2.args[s1]);
3541 /* Already Preallocated? */
3542 if (!(var->flags & PREALLOC)) {
3543 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3544 M_LST(s2, REG_SP, s1 * 8);
3548 /* is a patcher function set? */
3550 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3551 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3552 iptr->sx.s23.s3.c.ref, 0);
3555 /* a0 = dimension count */
3557 M_MOV_IMM(iptr->s1.argcount, REG_A0);
3559 /* a1 = classinfo */
3561 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3563 /* a2 = pointer to dimensions = stack pointer */
3565 M_MOV(REG_SP, REG_A2);
3567 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3570 /* check for exception before result assignment */
3574 codegen_add_fillinstacktrace_ref(cd);
3576 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3577 M_INTMOVE(REG_RESULT, s1);
3578 emit_store_dst(jd, iptr, s1);
3583 exceptions_throw_internalerror("Unknown ICMD %d", iptr->opc);
3587 } /* for instruction */
3589 MCODECHECK(512); /* XXX require a lower number? */
3591 /* At the end of a basic block we may have to append some nops,
3592 because the patcher stub calling code might be longer than the
3593 actual instruction. So codepatching does not change the
3594 following block unintentionally. */
3596 if (cd->mcodeptr < cd->lastmcodeptr) {
3597 while (cd->mcodeptr < cd->lastmcodeptr) {
3602 } /* if (bptr -> flags >= BBREACHED) */
3603 } /* for basic block */
3605 dseg_createlinenumbertable(cd);
3607 /* generate stubs */
3609 emit_exception_stubs(jd);
3610 emit_patcher_stubs(jd);
3612 emit_replacement_stubs(jd);
3617 /* everything's ok */
3623 /* createcompilerstub **********************************************************
3625 Creates a stub routine which calls the compiler.
3627 *******************************************************************************/
3629 #define COMPILERSTUB_DATASIZE (3 * SIZEOF_VOID_P)
3630 #define COMPILERSTUB_CODESIZE (SZ_BRAS + SZ_AHI + (2 * SZ_L) + SZ_BR)
3632 #define COMPILERSTUB_SIZE (COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE)
3635 u1 *createcompilerstub(methodinfo *m)
3637 u1 *s; /* memory to hold the stub */
3643 s = CNEW(u1, COMPILERSTUB_SIZE);
3645 /* set data pointer and code pointer */
3648 s = s + COMPILERSTUB_DATASIZE;
3650 /* mark start of dump memory area */
3652 dumpsize = dump_size();
3654 cd = DNEW(codegendata);
3657 /* Store the codeinfo pointer in the same place as in the
3658 methodheader for compiled methods. */
3660 code = code_codeinfo_new(m);
3662 d[0] = (ptrint) asm_call_jit_compiler;
3664 d[2] = (ptrint) code;
3666 /* code for the stub */
3668 /* don't touch ITMP3 as it cointains the return address */
3670 M_ILD(REG_ITMP1, REG_PV, -2 * 4); /* methodinfo */
3671 /* TODO where is methodpointer loaded into itmp2? is it already inside? */
3672 M_ILD(REG_PV, REG_PV, -3 * 4); /* compiler pointer */
3675 #if defined(ENABLE_STATISTICS)
3677 count_cstub_len += COMPILERSTUB_SIZE;
3680 /* release dump area */
3682 dump_release(dumpsize);
3688 /* createnativestub ************************************************************
3690 Creates a stub routine which calls a native method.
3692 *******************************************************************************/
3695 arguments on stack \
3696 -------------------------------------------------| <- SP on nativestub entry
3698 callee saved int regs (none) |
3699 callee saved float regs (none) | stack frame like in cacao
3700 local variable slots (none) |
3701 arguments for calling methods (none) /
3702 ------------------------------------------------------------------ <- datasp
3707 96 - ... on stack parameters (nmd->memuse slots) \ stack frame like in ABI
3708 0 - 96 register save area for callee /
3709 -------------------------------------------------------- <- SP native method
3711 SP after method entry
3714 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3722 s4 i, j; /* count variables */
3727 /* get required compiler data */
3734 /* initialize variables */
3737 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3739 /* calculate stack frame size */
3741 cd->stackframesize =
3742 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3743 sizeof(localref_table) / SIZEOF_VOID_P +
3744 INT_ARG_CNT + FLT_ARG_CNT +
3745 1 + /* functionptr, TODO: store in data segment */
3748 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3751 cd->stackframesize =
3752 1 + /* r14 - return address */ +
3753 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3754 sizeof(localref_table) / SIZEOF_VOID_P +
3756 (INT_ARG_CNT + FLT_ARG_CNT) * 2 +
3757 nmd->memuse + /* parameter passing */
3758 96 / SIZEOF_VOID_P /* required by ABI */;
3761 /* create method header */
3763 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3764 (void) dseg_add_unique_s4(cd, cd->stackframesize * 8); /* FrameSize */
3765 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3766 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3767 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3768 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3769 (void) dseg_addlinenumbertablesize(cd);
3770 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3772 /* generate native method profiling code */
3774 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3775 /* count frequency */
3777 M_MOV_IMM(code, REG_ITMP3);
3778 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3782 /* generate stub code */
3784 N_AHI(REG_SP, -(cd->stackframesize * SIZEOF_VOID_P));
3786 /* save return address */
3788 N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, RN, REG_SP);
3791 #if !defined(NDEBUG)
3792 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3793 emit_verbosecall_enter(jd);
3797 /* get function address (this must happen before the stackframeinfo) */
3799 #if !defined(WITH_STATIC_CLASSPATH)
3801 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, 0);
3804 disp = dseg_add_functionptr(cd, f);
3805 M_ILD(REG_ITMP1, REG_PV, disp);
3807 j = 96 + (nmd->memuse * 4);
3809 /* todo some arg registers are not volatile in C-abi terms */
3811 /* save integer and float argument registers */
3813 for (i = 0; i < md->paramcount; i++) {
3814 if (! md->params[i].inmemory) {
3815 s1 = md->params[i].regoff;
3817 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3818 if (IS_2_WORD_TYPE(t)) {
3819 /* todo store multiple */
3820 N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3821 N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3823 N_ST(rd->argintregs[s1], j, RN, REG_SP);
3826 if (IS_2_WORD_TYPE(t)) {
3827 N_STD(rd->argfltregs[s1], j, RN, REG_SP);
3829 N_STE(rd->argfltregs[s1], j, RN, REG_SP);
3837 N_ST(REG_ITMP1, j, RN, REG_SP);
3839 /* create dynamic stack info */
3841 N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
3842 N_LR(REG_A1, REG_PV); /* pv */
3843 N_LAE(REG_A2, cd->stackframesize * 4, RN, REG_SP); /* old SP */
3844 N_L(REG_A3, (cd->stackframesize - 1) * 4, RN, REG_SP); /* return address */
3846 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3847 M_ILD(REG_ITMP1, REG_PV, disp);
3849 M_CALL(REG_ITMP1); /* call */
3851 /* restore integer and float argument registers */
3853 j = 96 + (nmd->memuse * 4);
3855 for (i = 0; i < md->paramcount; i++) {
3856 if (! md->params[i].inmemory) {
3857 s1 = md->params[i].regoff;
3859 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3860 if (IS_2_WORD_TYPE(t)) {
3861 /* todo load multiple ! */
3862 N_L(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3863 N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3865 N_L(rd->argintregs[s1], j, RN, REG_SP);
3868 if (IS_2_WORD_TYPE(t)) {
3869 N_LD(rd->argfltregs[s1], j, RN, REG_SP);
3871 N_LE(rd->argfltregs[s1], j, RN, REG_SP);
3879 N_L(REG_ITMP1, j, RN, REG_SP);
3881 /* copy or spill arguments to new locations */
3883 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3884 t = md->paramtypes[i].type;
3886 if (IS_INT_LNG_TYPE(t)) {
3888 if (!md->params[i].inmemory) {
3890 s1 = rd->argintregs[md->params[i].regoff];
3892 if (!nmd->params[j].inmemory) {
3893 s2 = rd->argintregs[nmd->params[j].regoff];
3894 if (IS_2_WORD_TYPE(t)) {
3895 N_LR(GET_HIGH_REG(s2), GET_HIGH_REG(s1));
3896 N_LR(GET_LOW_REG(s2), GET_LOW_REG(s1));
3901 s2 = nmd->params[j].regoff;
3902 if (IS_2_WORD_TYPE(t)) {
3903 N_LM(GET_LOW_REG(s1), GET_HIGH_REG(s1), 96 + (s2 * 4), REG_SP);
3905 N_L(s1, 96 + (s2 * 4), RN, REG_SP);
3910 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3911 s2 = nmd->params[j].regoff;
3913 if (IS_2_WORD_TYPE(t)) {
3914 N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3916 N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3921 /* We only copy spilled float arguments, as the float argument */
3922 /* registers keep unchanged. */
3924 if (md->params[i].inmemory) {
3925 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3926 s2 = nmd->params[j].regoff;
3928 if (IS_2_WORD_TYPE(t)) {
3929 N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3931 N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3937 /* put class into second argument register */
3939 if (m->flags & ACC_STATIC) {
3940 disp = dseg_add_address(cd, m->class);
3941 M_ILD(REG_A1, REG_PV, disp);
3944 /* put env into first argument register */
3946 disp = dseg_add_address(cd, _Jv_env);
3947 M_ILD(REG_A0, REG_PV, disp);
3949 /* do the native function call */
3951 M_CALL(REG_ITMP1); /* call */
3953 /* save return value */
3955 t = md->returntype.type;
3957 if (t != TYPE_VOID) {
3958 if (IS_INT_LNG_TYPE(t)) {
3959 if (IS_2_WORD_TYPE(t)) {
3960 N_STM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3962 N_ST(REG_RESULT, 96, RN, REG_SP);
3965 if (IS_2_WORD_TYPE(t)) {
3966 N_STD(REG_FRESULT, 96, RN, REG_SP);
3968 N_STE(REG_FRESULT, 96, RN, REG_SP);
3974 #if !defined(NDEBUG)
3975 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3976 emit_verbosecall_exit(jd);
3980 /* remove native stackframe info */
3982 N_LAE(REG_A0, cd->stackframesize * 4, RN, REG_SP);
3983 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3984 M_ILD(REG_ITMP1, REG_PV, disp);
3986 N_LR(REG_ITMP3, REG_RESULT);
3988 /* restore return value */
3990 if (t != TYPE_VOID) {
3991 if (IS_INT_LNG_TYPE(t)) {
3992 if (IS_2_WORD_TYPE(t)) {
3993 N_LM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3995 N_L(REG_RESULT, 96, RN, REG_SP);
3998 if (IS_2_WORD_TYPE(t)) {
3999 N_LD(REG_FRESULT, 96, RN, REG_SP);
4001 N_LE(REG_FRESULT, 96, RN, REG_SP);
4006 /* remove stackframe */
4008 N_AHI(REG_SP, cd->stackframesize * 4);
4010 /* test for exception */
4012 N_LTR(REG_ITMP3, REG_ITMP3);
4013 N_BRC(DD_NE, SZ_BRC + SZ_BC);
4014 N_BC(DD_ANY, 0, RN, REG_SP); /* return */
4016 /* handle exception */
4021 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
4022 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8); /* get return address from stack */
4023 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
4025 M_MOV_IMM(asm_handle_nat_exception, REG_ITMP3);
4028 /* generate patcher stubs */
4030 emit_patcher_stubs(jd);
4035 return code->entrypoint;
4042 * These are local overrides for various environment variables in Emacs.
4043 * Please do not remove this and leave it at the end of the file, where
4044 * Emacs will automagically detect them.
4045 * ---------------------------------------------------------------------
4048 * indent-tabs-mode: t
4052 * vim:noexpandtab:sw=4:ts=4: