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 7486 2007-03-08 13:50:07Z twisti $
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 "vmcore/loader.h"
62 #include "vmcore/options.h"
63 #include "vmcore/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"
76 #include "vm/jit/stacktrace.h"
78 #if defined(ENABLE_LSRA)
79 # include "vm/jit/allocator/lsra.h"
82 #define OOPS() assert(0);
87 u1 *createcompilerstub(methodinfo *m) {
96 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd) {
98 return createcompilerstub(NULL);
104 /* codegen *********************************************************************
106 Generates machine code.
108 *******************************************************************************/
111 bool codegen(jitdata *jd)
117 s4 len, s1, s2, s3, d, disp;
120 varinfo *var, *var1, *var2, *dst;
124 constant_classref *cr;
125 unresolved_class *uc;
126 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
127 unresolved_method *um;
128 builtintable_entry *bte;
131 unresolved_field *uf;
134 rplpoint *replacementpoint;
138 /* get required compiler data */
145 /* prevent compiler warnings */
158 /* space to save used callee saved registers */
160 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
161 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse) * 2;
163 cd->stackframesize = rd->memuse + savedregs_num + 1 /* space to save RA */;
166 * As REG_ITMP3 == REG_RA, do not touch REG_ITMP3, until it has been saved.
169 #if defined(ENABLE_THREADS)
170 /* space to save argument of monitor_enter */
171 OOPS(); /* see powerpc */
173 if (checksync && (m->flags & ACC_SYNCHRONIZED))
174 cd->stackframesize++;
178 /* Keep stack of non-leaf functions 16-byte aligned for calls into
179 native code e.g. libc or jni (alignment problems with
182 if (!jd->isleafmethod || opt_verbosecall)
183 /* TODO really 16 bytes ? */
184 cd->stackframesize = (cd->stackframesize + 3) & ~3;
186 /* create method header */
188 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
189 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
191 #if defined(ENABLE_THREADS)
192 /* IsSync contains the offset relative to the stack pointer for the
193 argument of monitor_exit used in the exception handler. Since the
194 offset could be zero and give a wrong meaning of the flag it is
198 if (checksync && (m->flags & ACC_SYNCHRONIZED))
199 (void) dseg_add_unique_s4(cd, (rd->memuse + 1) * 4); /* IsSync */
203 (void) dseg_add_unique_s4(cd, 0);*/ /* IsSync */
205 disp = dseg_add_unique_address(cd, 0);
207 (void) dseg_add_unique_s4(cd, jd->isleafmethod); /* IsLeaf */
208 (void) dseg_add_unique_s4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
209 (void) dseg_add_unique_s4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
211 (void) dseg_addlinenumbertablesize(cd);
213 (void) dseg_add_unique_s4(cd, jd->exceptiontablelength); /* ExTableSize */
215 /* create exception table */
217 for (ex = jd->exceptiontable; ex != NULL; ex = ex->down) {
218 dseg_add_target(cd, ex->start);
219 dseg_add_target(cd, ex->end);
220 dseg_add_target(cd, ex->handler);
221 (void) dseg_add_unique_address(cd, ex->catchtype.any);
224 /* generate method profiling code */
226 #if defined(ENABLE_PROFILING)
227 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
228 /* count frequency */
230 M_ALD(REG_ITMP1, REG_PV, CodeinfoPointer);
231 M_ILD(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
232 M_IADD_IMM(1, REG_ITMP2);
233 M_IST(REG_ITMP2, REG_ITMP1, OFFSET(codeinfo, frequency));
235 /* PROFILE_CYCLE_START; */
239 /* create stack frame (if necessary) */
241 if (cd->stackframesize)
242 M_ASUB_IMM(cd->stackframesize * 4, REG_SP);
244 N_LHI(REG_ITMP2, disp);
245 N_ST(REG_SP, 0, REG_ITMP2, REG_PV);
247 /* save used callee saved registers and return address */
249 p = cd->stackframesize;
250 p--; M_AST(REG_RA, REG_SP, p * 4);
252 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
253 p--; M_IST(rd->savintregs[i], REG_SP, p * 4);
255 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
256 p -= 2; M_DST(rd->savfltregs[i], REG_SP, p * 4);
259 /* take arguments out of register or stack frame */
263 for (p = 0, l = 0; p < md->paramcount; p++) {
264 t = md->paramtypes[p].type;
265 varindex = jd->local_map[l * 5 + t];
268 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
271 if (varindex == UNUSED)
276 s1 = md->params[p].regoff;
277 if (IS_INT_LNG_TYPE(t)) { /* integer args */
278 if (IS_2_WORD_TYPE(t))
279 s2 = PACK_REGS(rd->argintregs[GET_LOW_REG(s1)],
280 rd->argintregs[GET_HIGH_REG(s1)]);
282 s2 = rd->argintregs[s1];
283 if (!md->params[p].inmemory) { /* register arguments */
284 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
285 if (IS_2_WORD_TYPE(t))
286 M_LNGMOVE(s2, var->vv.regoff);
288 M_INTMOVE(s2, var->vv.regoff);
290 } else { /* reg arg -> spilled */
291 if (IS_2_WORD_TYPE(t))
292 M_LST(s2, REG_SP, var->vv.regoff * 4);
294 M_IST(s2, REG_SP, var->vv.regoff * 4);
297 } else { /* stack arguments */
298 if (!IS_INMEMORY(var->flags)) { /* stack arg -> register */
299 if (IS_2_WORD_TYPE(t))
300 M_LLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
302 M_ILD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
304 } else { /* stack arg -> spilled */
305 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4);
306 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4);
307 if (IS_2_WORD_TYPE(t)) {
308 M_ILD(REG_ITMP1, REG_SP, (cd->stackframesize + s1) * 4 +4);
309 M_IST(REG_ITMP1, REG_SP, var->vv.regoff * 4 + 4);
314 } else { /* floating args */
315 if (!md->params[p].inmemory) { /* register arguments */
316 s2 = rd->argfltregs[s1];
317 if (!IS_INMEMORY(var->flags)) { /* reg arg -> register */
318 M_FLTMOVE(s2, var->vv.regoff);
320 } else { /* reg arg -> spilled */
321 if (IS_2_WORD_TYPE(t))
322 M_DST(s2, REG_SP, var->vv.regoff * 4);
324 M_FST(s2, REG_SP, var->vv.regoff * 4);
327 } else { /* stack arguments */
328 if (!IS_INMEMORY(var->flags)) { /* stack-arg -> register */
329 if (IS_2_WORD_TYPE(t))
330 M_DLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
333 M_FLD(var->vv.regoff, REG_SP, (cd->stackframesize + s1) * 4);
335 } else { /* stack-arg -> spilled */
336 if (IS_2_WORD_TYPE(t)) {
337 M_DLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
338 M_DST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
339 var->vv.regoff = cd->stackframesize + s1;
342 M_FLD(REG_FTMP1, REG_SP, (cd->stackframesize + s1) * 4);
343 M_FST(REG_FTMP1, REG_SP, var->vv.regoff * 4);
350 /* save monitorenter argument */
352 #if defined(ENABLE_THREADS)
353 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
354 /* stack offset for monitor argument */
358 if (opt_verbosecall) {
359 M_LSUB_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
361 for (p = 0; p < INT_ARG_CNT; p++)
362 M_LST(rd->argintregs[p], REG_SP, p * 8);
364 for (p = 0; p < FLT_ARG_CNT; p++)
365 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
367 s1 += INT_ARG_CNT + FLT_ARG_CNT;
370 /* decide which monitor enter function to call */
372 if (m->flags & ACC_STATIC) {
373 M_MOV_IMM(&m->class->object.header, REG_A0);
378 codegen_add_nullpointerexception_ref(cd);
381 M_AST(REG_A0, REG_SP, s1 * 8);
382 M_MOV_IMM(LOCK_monitor_enter, REG_ITMP1);
385 if (opt_verbosecall) {
386 for (p = 0; p < INT_ARG_CNT; p++)
387 M_LLD(rd->argintregs[p], REG_SP, p * 8);
389 for (p = 0; p < FLT_ARG_CNT; p++)
390 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
392 M_LADD_IMM((INT_ARG_CNT + FLT_ARG_CNT) * 8, REG_SP);
398 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
399 emit_verbosecall_enter(jd);
400 #endif /* !defined(NDEBUG) */
404 /* end of header generation */
406 replacementpoint = jd->code->rplpoints;
409 /* walk through all basic blocks */
411 for (bptr = jd->basicblocks; bptr != NULL; bptr = bptr->next) {
413 bptr->mpc = (u4) ((u1 *) cd->mcodeptr - cd->mcodebase);
415 if (bptr->flags >= BBREACHED) {
417 /* branch resolving */
419 codegen_resolve_branchrefs(cd, bptr);
421 /* handle replacement points */
424 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
425 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
429 assert(cd->lastmcodeptr <= cd->mcodeptr);
430 cd->lastmcodeptr = cd->mcodeptr + 5; /* 5 byte jmp patch */
434 /* copy interface registers to their destination */
439 /* generate basicblock profiling code */
441 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
442 /* count frequency */
444 M_MOV_IMM(code->bbfrequency, REG_ITMP3);
445 M_IINC_MEMBASE(REG_ITMP3, bptr->nr * 4);
447 /* if this is an exception handler, start profiling again */
449 if (bptr->type == BBTYPE_EXH)
453 #if defined(ENABLE_LSRA)
457 src = bptr->invars[len];
458 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
459 if (bptr->type == BBTYPE_EXH) {
460 /* d = reg_of_var(rd, src, REG_ITMP1); */
461 if (!IS_INMEMORY(src->flags))
465 M_INTMOVE(REG_ITMP1, d);
466 emit_store(jd, NULL, src, d);
476 var = VAR(bptr->invars[len]);
477 if ((len == bptr->indepth-1) && (bptr->type != BBTYPE_STD)) {
478 if (bptr->type == BBTYPE_EXH) {
479 d = codegen_reg_of_var(0, var, REG_ITMP1);
480 M_INTMOVE(REG_ITMP1, d);
481 emit_store(jd, NULL, var, d);
485 assert((var->flags & INOUT));
488 #if defined(ENABLE_LSRA)
491 /* walk through all instructions */
496 for (iptr = bptr->iinstr; len > 0; len--, iptr++) {
497 if (iptr->line != currentline) {
498 dseg_addlinenumber(cd, iptr->line);
499 currentline = iptr->line;
502 MCODECHECK(1024); /* 1KB should be enough */
505 case ICMD_NOP: /* ... ==> ... */
506 case ICMD_POP: /* ..., value ==> ... */
507 case ICMD_POP2: /* ..., value, value ==> ... */
508 case ICMD_INLINE_START: /* internal ICMDs */
509 case ICMD_INLINE_END:
512 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
513 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
516 codegen_add_nullpointerexception_ref(cd);
519 /* constant operations ************************************************/
521 case ICMD_ICONST: /* ... ==> ..., constant */
522 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
523 ICONST(d, iptr->sx.val.i);
524 emit_store_dst(jd, iptr, d);
527 case ICMD_LCONST: /* ... ==> ..., constant */
530 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
531 LCONST(d, iptr->sx.val.l);
532 emit_store_dst(jd, iptr, d);
536 case ICMD_FCONST: /* ... ==> ..., constant */
537 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
538 disp = dseg_add_float(cd, iptr->sx.val.f);
539 M_FLDN(d, REG_PV, disp, REG_ITMP1);
540 emit_store_dst(jd, iptr, d);
543 case ICMD_DCONST: /* ... ==> ..., constant */
546 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
547 disp = dseg_add_double(cd, iptr->sx.val.d);
548 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, d);
549 emit_store_dst(jd, iptr, d);
553 case ICMD_ACONST: /* ... ==> ..., constant */
554 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
556 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
557 cr = iptr->sx.val.c.ref;
558 disp = dseg_add_unique_address(cd, cr);
560 /* PROFILE_CYCLE_STOP; */
562 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_classinfo,
565 /* PROFILE_CYCLE_START; */
567 M_ALD(d, REG_PV, disp);
569 if (iptr->sx.val.anyptr == 0) {
572 disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
573 M_ALD(d, REG_PV, disp);
576 emit_store_dst(jd, iptr, d);
580 /* load/store/copy/move operations ************************************/
582 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
583 case ICMD_ALOAD: /* s1 = local variable */
587 case ICMD_ISTORE: /* ..., value ==> ... */
593 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
597 if (!(iptr->flags.bits & INS_FLAG_RETADDR))
598 emit_copy(jd, iptr, VAROP(iptr->s1), VAROP(iptr->dst));
601 /* integer operations *************************************************/
603 case ICMD_INEG: /* ..., value ==> ..., - value */
605 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
606 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
608 emit_store_dst(jd, iptr, d);
612 case ICMD_LNEG: /* ..., value ==> ..., - value */
615 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
616 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
619 emit_store_dst(jd, iptr, d);
623 case ICMD_I2L: /* ..., value ==> ..., value */
626 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
627 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
629 emit_store_dst(jd, iptr, d);
633 case ICMD_L2I: /* ..., value ==> ..., value */
636 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
637 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
639 emit_store_dst(jd, iptr, d);
643 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
646 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
647 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
649 emit_store_dst(jd, iptr, d);
653 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
654 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
655 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
659 emit_store_dst(jd, iptr, d);
662 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
665 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
666 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
668 emit_store_dst(jd, iptr, d);
673 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
675 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
676 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
677 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
684 emit_store_dst(jd, iptr, d);
689 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
690 /* sx.val.i = constant */
691 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
692 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
695 if (N_VALID_IMM(iptr->sx.val.i)) {
696 M_IADD_IMM(iptr->sx.val.i, d);
698 disp = dseg_add_s4(cd, iptr->sx.val.i);
699 M_ILD(REG_ITMP2, REG_PV, disp);
700 M_IADD(REG_ITMP2, d);
702 emit_store_dst(jd, iptr, d);
705 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
708 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
709 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
710 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
717 emit_store_dst(jd, iptr, d);
721 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
722 /* sx.val.l = constant */
725 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
726 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
728 if (IS_IMM32(iptr->sx.val.l))
729 M_LADD_IMM(iptr->sx.val.l, d);
731 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
732 M_LADD(REG_ITMP2, d);
734 emit_store_dst(jd, iptr, d);
738 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
740 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
741 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
742 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
744 M_INTMOVE(s1, REG_ITMP1);
745 M_ISUB(s2, REG_ITMP1);
746 M_INTMOVE(REG_ITMP1, d);
751 emit_store_dst(jd, iptr, d);
755 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
756 /* sx.val.i = constant */
758 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
759 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
762 M_ISUB_IMM(iptr->sx.val.i, d);
763 emit_store_dst(jd, iptr, d);
767 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
770 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
771 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
772 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
774 M_INTMOVE(s1, REG_ITMP1);
775 M_LSUB(s2, REG_ITMP1);
776 M_INTMOVE(REG_ITMP1, d);
781 emit_store_dst(jd, iptr, d);
785 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
786 /* sx.val.l = constant */
789 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
790 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
792 if (IS_IMM32(iptr->sx.val.l))
793 M_LSUB_IMM(iptr->sx.val.l, d);
795 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
796 M_LSUB(REG_ITMP2, d);
798 emit_store_dst(jd, iptr, d);
802 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
806 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
807 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
814 emit_store_dst(jd, iptr, d);
818 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
819 /* sx.val.i = constant */
820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
821 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
823 if (iptr->sx.val.i == 2) {
825 } else if (N_VALID_IMM(iptr->sx.val.i)) {
826 M_IMUL_IMM(iptr->sx.val.i, d);
828 disp = dseg_add_s4(cd, iptr->sx.val.i);
829 M_ILD(REG_ITMP2, REG_PV, disp);
830 M_IMUL(REG_ITMP2, d);
832 emit_store_dst(jd, iptr, d);
835 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
838 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
839 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
840 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
847 emit_store_dst(jd, iptr, d);
851 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
852 /* sx.val.l = constant */
855 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
856 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
857 if (IS_IMM32(iptr->sx.val.l))
858 M_LMUL_IMM(s1, iptr->sx.val.l, d);
860 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
862 M_LMUL(REG_ITMP2, d);
864 emit_store_dst(jd, iptr, d);
868 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
869 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
871 /* For this operation we need a register pair.
872 * We will use r0 and itmp1 and will backup r0.
875 M_INTMOVE(R0, REG_ITMP3);
877 s1 = emit_load_s1(jd, iptr, R0);
882 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
886 if (iptr->opc == ICMD_IREM) {
887 d = codegen_reg_of_dst(jd, iptr, R0);
890 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
891 M_INTMOVE(REG_ITMP1, d);
894 emit_store_dst(jd, iptr, d);
896 M_INTMOVE(REG_ITMP3, R0);
900 case ICMD_IDIVPOW2: /* ..., value ==> ..., value >> constant */
901 /* sx.val.i = constant */
904 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
905 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
906 M_INTMOVE(s1, REG_ITMP1);
907 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
908 emit_leal_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
909 emit_cmovccl_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
910 emit_shiftl_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
911 emit_mov_reg_reg(cd, REG_ITMP1, d);
912 emit_store_dst(jd, iptr, d);
916 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
917 /* sx.val.i = constant */
920 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
921 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
922 M_INTMOVE(s1, REG_ITMP1);
923 emit_alul_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
924 emit_leal_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
925 emit_cmovccl_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
926 emit_alul_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
927 emit_alul_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
928 emit_mov_reg_reg(cd, REG_ITMP1, d);
929 emit_store_dst(jd, iptr, d);
934 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
937 var1 = VAROP(iptr->s1);
938 var2 = VAROP(iptr->sx.s23.s2);
939 dst = VAROP(iptr->dst);
941 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
943 if (IS_INMEMORY(var1->flags))
944 M_LLD(RAX, REG_SP, var1->vv.regoff * 8);
946 M_INTMOVE(var1->vv.regoff, RAX);
948 if (IS_INMEMORY(var2->flags))
949 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
951 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
956 codegen_add_arithmeticexception_ref(cd);
959 /* check as described in jvm spec */
960 disp = dseg_add_s8(cd, 0x8000000000000000LL);
961 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, RAX);
963 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
964 M_BEQ(3 + 2 + 3); /* 6 bytes */
966 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
968 emit_idiv_reg(cd, REG_ITMP3);
970 if (IS_INMEMORY(dst->flags)) {
971 M_LST(RAX, REG_SP, dst->vv.regoff * 8);
972 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
975 M_INTMOVE(RAX, dst->vv.regoff);
977 if (dst->vv.regoff != RDX) {
978 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
984 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
987 var1 = VAROP(iptr->s1);
988 var2 = VAROP(iptr->sx.s23.s2);
989 dst = VAROP(iptr->dst);
991 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
993 if (IS_INMEMORY(var1->flags))
994 M_LLD(REG_ITMP1, REG_SP, var1->vv.regoff * 8);
996 M_INTMOVE(var1->vv.regoff, REG_ITMP1);
998 if (IS_INMEMORY(var2->flags))
999 M_LLD(REG_ITMP3, REG_SP, var2->vv.regoff * 8);
1001 M_INTMOVE(var2->vv.regoff, REG_ITMP3);
1003 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1004 M_INTMOVE(s1, REG_ITMP1);
1005 s2 = emit_load_s2(jd, iptr, REG_ITMP3);
1006 M_INTMOVE(s2, REG_ITMP3);
1011 codegen_add_arithmeticexception_ref(cd);
1014 M_MOV(RDX, REG_ITMP2); /* save %rdx, cause it's an argument register */
1016 /* check as described in jvm spec */
1017 disp = dseg_add_s8(cd, 0x8000000000000000LL);
1018 M_LCMP_MEMBASE(RIP, -((cd->mcodeptr + 7) - cd->mcodebase) + disp, REG_ITMP1);
1022 emit_alul_reg_reg(cd, ALU_XOR, RDX, RDX); /* 2 bytes */
1024 M_LXOR(RDX, RDX); /* 3 bytes */
1025 M_LCMP_IMM(-1, REG_ITMP3); /* 4 bytes */
1026 M_BEQ(2 + 3); /* 6 bytes */
1029 emit_idiv_reg(cd, REG_ITMP3);
1031 if (IS_INMEMORY(dst->flags)) {
1032 M_LST(RDX, REG_SP, dst->vv.regoff * 8);
1033 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1036 M_INTMOVE(RDX, dst->vv.regoff);
1038 if (dst->vv.regoff != RDX) {
1039 M_MOV(REG_ITMP2, RDX); /* restore %rdx */
1045 case ICMD_LDIVPOW2: /* ..., value ==> ..., value >> constant */
1046 /* sx.val.i = constant */
1049 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1050 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1051 M_INTMOVE(s1, REG_ITMP1);
1052 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1053 emit_lea_membase_reg(cd, REG_ITMP1, (1 << iptr->sx.val.i) - 1, REG_ITMP2);
1054 emit_cmovcc_reg_reg(cd, CC_LE, REG_ITMP2, REG_ITMP1);
1055 emit_shift_imm_reg(cd, SHIFT_SAR, iptr->sx.val.i, REG_ITMP1);
1056 emit_mov_reg_reg(cd, REG_ITMP1, d);
1057 emit_store_dst(jd, iptr, d);
1061 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1062 /* sx.val.l = constant */
1065 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1066 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1067 M_INTMOVE(s1, REG_ITMP1);
1068 emit_alu_imm_reg(cd, ALU_CMP, -1, REG_ITMP1);
1069 emit_lea_membase_reg(cd, REG_ITMP1, iptr->sx.val.i, REG_ITMP2);
1070 emit_cmovcc_reg_reg(cd, CC_G, REG_ITMP1, REG_ITMP2);
1071 emit_alu_imm_reg(cd, ALU_AND, -1 - (iptr->sx.val.i), REG_ITMP2);
1072 emit_alu_reg_reg(cd, ALU_SUB, REG_ITMP2, REG_ITMP1);
1073 emit_mov_reg_reg(cd, REG_ITMP1, d);
1074 emit_store_dst(jd, iptr, d);
1078 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1081 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1082 emit_ishift(jd, SHIFT_SHL, iptr);
1086 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1087 /* sx.val.i = constant */
1090 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1091 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1093 M_ISLL_IMM(iptr->sx.val.i, d);
1094 emit_store_dst(jd, iptr, d);
1098 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1101 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1102 emit_ishift(jd, SHIFT_SAR, iptr);
1106 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1107 /* sx.val.i = constant */
1110 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1111 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1113 M_ISRA_IMM(iptr->sx.val.i, d);
1114 emit_store_dst(jd, iptr, d);
1118 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1121 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1122 emit_ishift(jd, SHIFT_SHR, iptr);
1126 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1127 /* sx.val.i = constant */
1130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1131 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1133 M_ISRL_IMM(iptr->sx.val.i, d);
1134 emit_store_dst(jd, iptr, d);
1138 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1141 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1142 emit_lshift(jd, SHIFT_SHL, iptr);
1146 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1147 /* sx.val.i = constant */
1150 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1151 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1153 M_LSLL_IMM(iptr->sx.val.i, d);
1154 emit_store_dst(jd, iptr, d);
1158 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1161 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1162 emit_lshift(jd, SHIFT_SAR, iptr);
1166 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1167 /* sx.val.i = constant */
1170 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1171 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1173 M_LSRA_IMM(iptr->sx.val.i, d);
1174 emit_store_dst(jd, iptr, d);
1178 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1181 d = codegen_reg_of_dst(jd, iptr, REG_NULL);
1182 emit_lshift(jd, SHIFT_SHR, iptr);
1186 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1187 /* sx.val.l = constant */
1190 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1191 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1193 M_LSRL_IMM(iptr->sx.val.i, d);
1194 emit_store_dst(jd, iptr, d);
1198 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1201 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1202 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1203 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1210 emit_store_dst(jd, iptr, d);
1214 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1215 /* sx.val.i = constant */
1218 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1219 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1221 M_IAND_IMM(iptr->sx.val.i, d);
1222 emit_store_dst(jd, iptr, d);
1226 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1229 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1230 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1231 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1238 emit_store_dst(jd, iptr, d);
1242 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1243 /* sx.val.l = constant */
1246 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1247 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1249 if (IS_IMM32(iptr->sx.val.l))
1250 M_LAND_IMM(iptr->sx.val.l, d);
1252 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1253 M_LAND(REG_ITMP2, d);
1255 emit_store_dst(jd, iptr, d);
1259 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1263 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1264 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1271 emit_store_dst(jd, iptr, d);
1275 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1276 /* sx.val.i = constant */
1279 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1280 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1282 M_IOR_IMM(iptr->sx.val.i, d);
1283 emit_store_dst(jd, iptr, d);
1287 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1290 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1291 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1292 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1299 emit_store_dst(jd, iptr, d);
1303 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1304 /* sx.val.l = constant */
1307 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1308 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1310 if (IS_IMM32(iptr->sx.val.l))
1311 M_LOR_IMM(iptr->sx.val.l, d);
1313 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1314 M_LOR(REG_ITMP2, d);
1316 emit_store_dst(jd, iptr, d);
1320 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1323 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1324 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1325 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1332 emit_store_dst(jd, iptr, d);
1336 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1337 /* sx.val.i = constant */
1340 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1341 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1343 M_IXOR_IMM(iptr->sx.val.i, d);
1344 emit_store_dst(jd, iptr, d);
1348 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
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);
1360 emit_store_dst(jd, iptr, d);
1364 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1365 /* sx.val.l = constant */
1368 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1369 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1371 if (IS_IMM32(iptr->sx.val.l))
1372 M_LXOR_IMM(iptr->sx.val.l, d);
1374 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
1375 M_LXOR(REG_ITMP2, d);
1377 emit_store_dst(jd, iptr, d);
1382 /* floating operations ************************************************/
1384 case ICMD_FNEG: /* ..., value ==> ..., - value */
1387 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1388 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1389 disp = dseg_add_s4(cd, 0x80000000);
1391 emit_movss_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1392 emit_xorps_reg_reg(cd, REG_FTMP2, d);
1393 emit_store_dst(jd, iptr, d);
1397 case ICMD_DNEG: /* ..., value ==> ..., - value */
1400 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1401 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1402 disp = dseg_add_s8(cd, 0x8000000000000000);
1404 emit_movd_membase_reg(cd, RIP, -((cd->mcodeptr + 9) - cd->mcodebase) + disp, REG_FTMP2);
1405 emit_xorpd_reg_reg(cd, REG_FTMP2, d);
1406 emit_store_dst(jd, iptr, d);
1410 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1413 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1414 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1415 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1422 emit_store_dst(jd, iptr, d);
1426 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1429 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1430 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1431 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1438 emit_store_dst(jd, iptr, d);
1442 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1445 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1446 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1447 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1449 M_FLTMOVE(s2, REG_FTMP2);
1454 emit_store_dst(jd, iptr, d);
1458 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1461 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1462 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1463 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1465 M_FLTMOVE(s2, REG_FTMP2);
1470 emit_store_dst(jd, iptr, d);
1474 case ICMD_FMUL: /* ..., 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_DMUL: /* ..., 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_FDIV: /* ..., 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_DDIV: /* ..., 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_I2F: /* ..., value ==> ..., (float) value */
1537 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1538 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1540 emit_store_dst(jd, iptr, d);
1543 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1544 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1545 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1547 emit_store_dst(jd, iptr, d);
1550 case ICMD_L2F: /* ..., value ==> ..., (float) value */
1553 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1554 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1556 emit_store_dst(jd, iptr, d);
1560 case ICMD_L2D: /* ..., value ==> ..., (double) value */
1563 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1564 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
1566 emit_store_dst(jd, iptr, d);
1570 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1571 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1572 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1574 emit_store_dst(jd, iptr, d);
1575 /* TODO: corner cases ? */
1578 case ICMD_D2I: /* ..., value ==> ..., (int) value */
1581 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1582 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1584 M_ICMP_IMM(0x80000000, d); /* corner cases */
1585 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1586 ((REG_RESULT == d) ? 0 : 3);
1588 M_FLTMOVE(s1, REG_FTMP1);
1589 M_MOV_IMM(asm_builtin_d2i, REG_ITMP2);
1591 M_INTMOVE(REG_RESULT, d);
1592 emit_store_dst(jd, iptr, d);
1596 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1599 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1600 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1602 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1603 M_LCMP(REG_ITMP2, d); /* corner cases */
1604 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1605 ((REG_RESULT == d) ? 0 : 3);
1607 M_FLTMOVE(s1, REG_FTMP1);
1608 M_MOV_IMM(asm_builtin_f2l, REG_ITMP2);
1610 M_INTMOVE(REG_RESULT, d);
1611 emit_store_dst(jd, iptr, d);
1615 case ICMD_D2L: /* ..., value ==> ..., (long) value */
1618 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1619 d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
1621 M_MOV_IMM(0x8000000000000000, REG_ITMP2);
1622 M_LCMP(REG_ITMP2, d); /* corner cases */
1623 disp = ((s1 == REG_FTMP1) ? 0 : 5) + 10 + 3 +
1624 ((REG_RESULT == d) ? 0 : 3);
1626 M_FLTMOVE(s1, REG_FTMP1);
1627 M_MOV_IMM(asm_builtin_d2l, REG_ITMP2);
1629 M_INTMOVE(REG_RESULT, d);
1630 emit_store_dst(jd, iptr, d);
1634 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1635 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1636 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1638 emit_store_dst(jd, iptr, d);
1641 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1644 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1645 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1647 emit_store_dst(jd, iptr, d);
1651 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1652 /* == => 0, < => 1, > => -1 */
1655 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1656 /* == => 0, < => 1, > => -1 */
1658 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1659 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1660 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1664 M_BGT(SZ_BRC + SZ_BRC + SZ_BRC);
1665 M_BLT(SZ_BRC + SZ_BRC + SZ_LHI + SZ_BRC);
1666 M_BEQ(SZ_BRC + SZ_LHI + SZ_BRC + SZ_LHI + SZ_BRC);
1668 N_LHI(d, iptr->opc == ICMD_FCMPL ? 1 : -1); /* GT */
1669 M_BR(SZ_BRC + SZ_LHI + SZ_BRC + SZ_LHI);
1670 N_LHI(d, iptr->opc == ICMD_FCMPL ? -1 : 1); /* LT */
1671 M_BR(SZ_BRC + SZ_LHI);
1672 N_LHI(d, 0); /* EQ */
1674 emit_store_dst(jd, iptr, d);
1678 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1679 /* == => 0, < => 1, > => -1 */
1682 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1683 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1684 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1686 M_MOV_IMM(1, REG_ITMP1);
1687 M_MOV_IMM(-1, REG_ITMP2);
1688 emit_ucomisd_reg_reg(cd, s1, s2);
1689 M_CMOVB(REG_ITMP1, d);
1690 M_CMOVA(REG_ITMP2, d);
1691 M_CMOVP(REG_ITMP2, d); /* treat unordered as GT */
1692 emit_store_dst(jd, iptr, d);
1696 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1697 /* == => 0, < => 1, > => -1 */
1700 s1 = emit_load_s1(jd, iptr, REG_FTMP1);
1701 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
1702 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1704 M_MOV_IMM(1, REG_ITMP1);
1705 M_MOV_IMM(-1, REG_ITMP2);
1706 emit_ucomisd_reg_reg(cd, s1, s2);
1707 M_CMOVB(REG_ITMP1, d);
1708 M_CMOVA(REG_ITMP2, d);
1709 M_CMOVP(REG_ITMP1, d); /* treat unordered as LT */
1710 emit_store_dst(jd, iptr, d);
1715 /* memory operations **************************************************/
1717 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., (int) length */
1719 s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
1720 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1721 gen_nullptr_check(s1);
1722 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1723 emit_store_dst(jd, iptr, d);
1727 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1730 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1731 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1732 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1733 if (INSTRUCTION_MUST_CHECK(iptr)) {
1734 gen_nullptr_check(s1);
1737 emit_movsbq_memindex_reg(cd, OFFSET(java_bytearray, data[0]), s1, s2, 0, d);
1738 emit_store_dst(jd, iptr, d);
1742 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1744 s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
1745 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1746 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1748 emit_array_checks(cd, iptr, s1, s2);
1750 M_INTMOVE(s2, REG_ITMP2);
1751 M_ISLL_IMM(1, REG_ITMP2);
1753 N_LH(d, OFFSET(java_chararray, data[0]), REG_ITMP2, s1);
1754 emit_store_dst(jd, iptr, d);
1757 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1760 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1761 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1762 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1763 if (INSTRUCTION_MUST_CHECK(iptr)) {
1764 gen_nullptr_check(s1);
1767 emit_movswq_memindex_reg(cd, OFFSET(java_shortarray, data[0]), s1, s2, 1, d);
1768 emit_store_dst(jd, iptr, d);
1772 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1775 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1776 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1777 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1778 if (INSTRUCTION_MUST_CHECK(iptr)) {
1779 gen_nullptr_check(s1);
1782 emit_movl_memindex_reg(cd, OFFSET(java_intarray, data[0]), s1, s2, 2, d);
1783 emit_store_dst(jd, iptr, d);
1787 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1790 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1791 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1792 d = codegen_reg_of_dst(jd, iptr, REG_ITMP3);
1793 if (INSTRUCTION_MUST_CHECK(iptr)) {
1794 gen_nullptr_check(s1);
1797 emit_mov_memindex_reg(cd, OFFSET(java_longarray, data[0]), s1, s2, 3, d);
1798 emit_store_dst(jd, iptr, d);
1802 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1805 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1806 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1807 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1808 if (INSTRUCTION_MUST_CHECK(iptr)) {
1809 gen_nullptr_check(s1);
1812 emit_movss_memindex_reg(cd, OFFSET(java_floatarray, data[0]), s1, s2, 2, d);
1813 emit_store_dst(jd, iptr, d);
1817 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1820 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1821 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1822 d = codegen_reg_of_dst(jd, iptr, REG_FTMP3);
1823 if (INSTRUCTION_MUST_CHECK(iptr)) {
1824 gen_nullptr_check(s1);
1827 emit_movsd_memindex_reg(cd, OFFSET(java_doublearray, data[0]), s1, s2, 3, d);
1828 emit_store_dst(jd, iptr, d);
1832 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1833 s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
1834 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1835 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
1836 emit_array_checks(cd, iptr, s1, s2);
1838 M_INTMOVE(s2, REG_ITMP2);
1839 M_ISLL_IMM(2, REG_ITMP2); /* scale index by 4 */
1840 N_L(d, OFFSET(java_objectarray, data[0]), REG_ITMP2, s1);
1841 emit_store_dst(jd, iptr, d);
1844 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1847 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1848 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1849 if (INSTRUCTION_MUST_CHECK(iptr)) {
1850 gen_nullptr_check(s1);
1853 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1854 emit_movb_reg_memindex(cd, s3, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1858 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1860 s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
1861 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1862 emit_array_checks(cd, iptr, s1, s2);
1863 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1865 M_INTMOVE(s2, REG_ITMP2);
1866 M_ISLL_IMM(1, REG_ITMP2);
1868 N_STH(s3, OFFSET(java_chararray, data[0]), REG_ITMP2, s1);
1872 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1875 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1876 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1877 if (INSTRUCTION_MUST_CHECK(iptr)) {
1878 gen_nullptr_check(s1);
1881 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1882 emit_movw_reg_memindex(cd, s3, OFFSET(java_shortarray, data[0]), s1, s2, 1);
1886 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1889 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1890 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1891 if (INSTRUCTION_MUST_CHECK(iptr)) {
1892 gen_nullptr_check(s1);
1895 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1896 emit_movl_reg_memindex(cd, s3, OFFSET(java_intarray, data[0]), s1, s2, 2);
1900 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1903 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1904 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1905 if (INSTRUCTION_MUST_CHECK(iptr)) {
1906 gen_nullptr_check(s1);
1909 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1910 emit_mov_reg_memindex(cd, s3, OFFSET(java_longarray, data[0]), s1, s2, 3);
1914 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1917 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1918 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1919 if (INSTRUCTION_MUST_CHECK(iptr)) {
1920 gen_nullptr_check(s1);
1923 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1924 emit_movss_reg_memindex(cd, s3, OFFSET(java_floatarray, data[0]), s1, s2, 2);
1928 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 if (INSTRUCTION_MUST_CHECK(iptr)) {
1934 gen_nullptr_check(s1);
1937 s3 = emit_load_s3(jd, iptr, REG_FTMP3);
1938 emit_movsd_reg_memindex(cd, s3, OFFSET(java_doublearray, data[0]), s1, s2, 3);
1942 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1944 s1 = emit_load_s1_notzero(jd, iptr, REG_A0);
1945 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1946 emit_array_checks(cd, iptr, s1, s2);
1947 s3 = emit_load_s3(jd, iptr, REG_A1);
1949 M_INTMOVE(s1, REG_A0);
1950 M_INTMOVE(s3, REG_A1);
1952 disp = dseg_add_functionptr(cd, BUILTIN_canstore);
1953 ICONST(REG_ITMP3, disp);
1954 N_L(REG_PV, 0, REG_ITMP3, REG_PV);
1955 M_ISUB_IMM(96, REG_SP);
1956 M_JSR(REG_RA, REG_PV);
1957 M_IADD_IMM(96, REG_SP);
1958 N_BASR(REG_ITMP1, RN);
1959 disp = (s4) (cd->mcodeptr - cd->mcodebase);
1960 M_LDA(REG_PV, REG_ITMP1, -disp);
1964 codegen_add_arraystoreexception_ref(cd);
1966 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1967 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1968 s3 = emit_load_s3(jd, iptr, REG_ITMP3);
1970 M_INTMOVE(s2, REG_ITMP2);
1971 M_ISLL_IMM(2, REG_ITMP2);
1972 N_ST(s3, OFFSET(java_objectarray, data[0]), REG_ITMP2, s1);
1975 M_SAADDQ(s2, s1, REG_ITMP1); itmp1 := 4 * s2 + s1
1976 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1981 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1984 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1985 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1986 if (INSTRUCTION_MUST_CHECK(iptr)) {
1987 gen_nullptr_check(s1);
1990 emit_movb_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_bytearray, data[0]), s1, s2, 0);
1994 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1997 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
1998 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
1999 if (INSTRUCTION_MUST_CHECK(iptr)) {
2000 gen_nullptr_check(s1);
2003 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_chararray, data[0]), s1, s2, 1);
2007 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2010 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2011 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2012 if (INSTRUCTION_MUST_CHECK(iptr)) {
2013 gen_nullptr_check(s1);
2016 emit_movw_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_shortarray, data[0]), s1, s2, 1);
2020 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
2023 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2024 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2025 if (INSTRUCTION_MUST_CHECK(iptr)) {
2026 gen_nullptr_check(s1);
2029 emit_movl_imm_memindex(cd, iptr->sx.s23.s3.constval, OFFSET(java_intarray, data[0]), s1, s2, 2);
2033 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
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);
2043 if (IS_IMM32(iptr->sx.s23.s3.constval)) {
2044 emit_mov_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2046 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval & 0x00000000ffffffff), OFFSET(java_longarray, data[0]), s1, s2, 3);
2047 emit_movl_imm_memindex(cd, (u4) (iptr->sx.s23.s3.constval >> 32), OFFSET(java_longarray, data[0]) + 4, s1, s2, 3);
2052 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
2055 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2056 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2057 if (INSTRUCTION_MUST_CHECK(iptr)) {
2058 gen_nullptr_check(s1);
2061 emit_mov_imm_memindex(cd, 0, OFFSET(java_objectarray, data[0]), s1, s2, 3);
2066 case ICMD_GETSTATIC: /* ... ==> ..., value */
2068 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2069 uf = iptr->sx.s23.s3.uf;
2070 fieldtype = uf->fieldref->parseddesc.fd->type;
2071 disp = dseg_add_unique_address(cd, NULL);
2073 /* PROFILE_CYCLE_STOP; */
2075 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2077 /* PROFILE_CYCLE_START; */
2080 fi = iptr->sx.s23.s3.fmiref->p.field;
2081 fieldtype = fi->type;
2082 disp = dseg_add_address(cd, &(fi->value));
2084 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2087 codegen_add_patch_ref(cd, PATCHER_clinit, fi->class, 0);
2089 PROFILE_CYCLE_START;
2093 M_ALD(REG_ITMP1, REG_PV, disp);
2095 switch (fieldtype) {
2097 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2098 M_ILD(d, REG_ITMP1, 0);
2101 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2102 M_LLD(d, REG_ITMP1, 0);
2105 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2106 M_ALD(d, REG_ITMP1, 0);
2109 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2110 M_FLD(d, REG_ITMP1, 0);
2113 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2114 M_DLD(d, REG_ITMP1, 0);
2118 emit_store_dst(jd, iptr, d);
2122 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2124 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2125 uf = iptr->sx.s23.s3.uf;
2126 fieldtype = uf->fieldref->parseddesc.fd->type;
2127 disp = dseg_add_unique_address(cd, uf);
2129 codegen_addpatchref(cd, PATCHER_get_putstatic, uf, disp);
2132 fi = iptr->sx.s23.s3.fmiref->p.field;
2133 fieldtype = fi->type;
2134 disp = dseg_add_address(cd, &(fi->value));
2136 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2137 codegen_addpatchref(cd, PATCHER_clinit,
2141 M_ALD(REG_ITMP1, REG_PV, disp);
2142 switch (fieldtype) {
2144 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2145 M_IST(s1, REG_ITMP1, 0);
2148 s1 = emit_load_s1(jd, iptr, REG_ITMP23_PACKED);
2149 M_LST(s1, REG_ITMP1, 0);
2152 s1 = emit_load_s1(jd, iptr, REG_ITMP2);
2153 M_AST(s1, REG_ITMP1, 0);
2156 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2157 M_FST(s1, REG_ITMP1, 0);
2160 s1 = emit_load_s1(jd, iptr, REG_FTMP2);
2161 M_DST(s1, REG_ITMP1, 0);
2166 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2167 /* val = value (in current instruction) */
2168 /* following NOP) */
2171 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2172 uf = iptr->sx.s23.s3.uf;
2173 fieldtype = uf->fieldref->parseddesc.fd->type;
2174 disp = dseg_add_unique_address(cd, uf);
2176 codegen_add_patch_ref(cd, PATCHER_get_putstatic, uf, disp);
2179 fi = iptr->sx.s23.s3.fmiref->p.field;
2180 fieldtype = fi->type;
2181 disp = dseg_add_address(cd, &(fi->value));
2183 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class))
2184 codegen_add_patch_ref(cd, PATCHER_initialize_class, fi->class,
2188 M_ALD(REG_ITMP1, REG_PV, disp);
2190 switch (fieldtype) {
2192 M_IST(REG_ZERO, REG_ITMP1, 0);
2195 M_LST(REG_ZERO, REG_ITMP1, 0);
2198 M_AST(REG_ZERO, REG_ITMP1, 0);
2201 M_FST(REG_ZERO, REG_ITMP1, 0);
2204 M_DST(REG_ZERO, REG_ITMP1, 0);
2210 case ICMD_GETFIELD: /* ... ==> ..., value */
2212 s1 = emit_load_s1_notzero(jd, iptr, REG_ITMP1);
2213 emit_nullpointer_check(cd, iptr, s1);
2215 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2216 uf = iptr->sx.s23.s3.uf;
2217 fieldtype = uf->fieldref->parseddesc.fd->type;
2220 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2223 fi = iptr->sx.s23.s3.fmiref->p.field;
2224 fieldtype = fi->type;
2228 switch (fieldtype) {
2230 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2234 d = codegen_reg_of_dst(jd, iptr, REG_ITMP12_PACKED);
2235 if (GET_HIGH_REG(d) == s1) {
2236 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2237 M_ILD(GET_HIGH_REG(d), s1, disp);
2240 M_ILD(GET_HIGH_REG(d), s1, disp);
2241 M_ILD(GET_LOW_REG(d), s1, disp + 4);
2245 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
2249 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2253 d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
2257 emit_store_dst(jd, iptr, d);
2260 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2262 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2263 gen_nullptr_check(s1);
2265 s2 = emit_load_s2(jd, iptr, REG_IFTMP);
2267 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2268 uf = iptr->sx.s23.s3.uf;
2269 fieldtype = uf->fieldref->parseddesc.fd->type;
2273 fi = iptr->sx.s23.s3.fmiref->p.field;
2274 fieldtype = fi->type;
2278 if (IS_INT_LNG_TYPE(fieldtype)) {
2279 if (IS_2_WORD_TYPE(fieldtype))
2280 s2 = emit_load_s2(jd, iptr, REG_ITMP23_PACKED);
2282 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2285 s2 = emit_load_s2(jd, iptr, REG_FTMP2);
2287 if (INSTRUCTION_IS_UNRESOLVED(iptr))
2288 codegen_addpatchref(cd, PATCHER_get_putfield, uf, 0);
2290 switch (fieldtype) {
2292 M_IST(s2, s1, disp);
2295 /* TODO really order */
2296 M_IST(GET_LOW_REG(s2), s1, disp + 4); /* keep this order */
2297 M_IST(GET_HIGH_REG(s2), s1, disp); /* keep this order */
2300 M_AST(s2, s1, disp);
2303 M_FST(s2, s1, disp);
2306 M_DST(s2, s1, disp);
2311 case ICMD_PUTFIELDCONST: /* ..., objectref, value ==> ... */
2312 /* val = value (in current instruction) */
2313 /* following NOP) */
2316 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2317 gen_nullptr_check(s1);
2319 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2320 uf = iptr->sx.s23.s3.uf;
2321 fieldtype = uf->fieldref->parseddesc.fd->type;
2324 /* PROFILE_CYCLE_STOP; */
2326 codegen_add_patch_ref(cd, PATCHER_putfieldconst, uf, 0);
2328 /* PROFILE_CYCLE_START; */
2331 fi = iptr->sx.s23.s3.fmiref->p.field;
2332 fieldtype = fi->type;
2336 switch (fieldtype) {
2339 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2344 /* XXX why no check for IS_IMM32? */
2345 M_IST32_IMM(iptr->sx.s23.s2.constval, s1, disp);
2346 M_IST32_IMM(iptr->sx.s23.s2.constval >> 32, s1, disp + 4);
2353 /* branch operations **************************************************/
2355 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2357 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2358 M_INTMOVE(s1, REG_ITMP1_XPTR);
2362 #ifdef ENABLE_VERIFIER
2363 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2364 uc = iptr->sx.s23.s2.uc;
2366 codegen_add_patch_ref(cd, PATCHER_athrow_areturn, uc, 0);
2368 #endif /* ENABLE_VERIFIER */
2370 disp = dseg_add_functionptr(cd, asm_handle_exception);
2371 M_ALD(REG_ITMP2, REG_PV, disp);
2372 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2377 case ICMD_GOTO: /* ... ==> ... */
2378 case ICMD_RET: /* ... ==> ... */
2381 codegen_add_branch_ref(cd, iptr->dst.block);
2385 case ICMD_JSR: /* ... ==> ... */
2389 codegen_add_branch_ref(cd, iptr->sx.s23.s3.jsrtarget.block);
2393 case ICMD_IFNULL: /* ..., value ==> ... */
2394 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2397 codegen_add_branch_ref(cd, iptr->dst.block);
2400 case ICMD_IFNONNULL: /* ..., value ==> ... */
2401 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2404 codegen_add_branch_ref(cd, iptr->dst.block);
2407 case ICMD_IFEQ: /* ..., value ==> ... */
2408 case ICMD_IFLT: /* ..., value ==> ... */
2409 case ICMD_IFLE: /* ..., value ==> ... */
2410 case ICMD_IFNE: /* ..., value ==> ... */
2411 case ICMD_IFGT: /* ..., value ==> ... */
2412 case ICMD_IFGE: /* ..., value ==> ... */
2414 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2416 if (N_VALID_IMM(iptr->sx.val.i))
2417 N_CHI(s1, iptr->sx.val.i);
2419 disp = dseg_add_s4(cd, iptr->sx.val.i);
2420 N_LHI(REG_ITMP2, disp);
2421 N_CL(s1, 0, REG_ITMP2, REG_PV);
2424 switch (iptr->opc) {
2444 codegen_add_branch_ref(cd, iptr->dst.block);
2448 case ICMD_IF_LEQ: /* ..., value ==> ... */
2451 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2452 if (IS_IMM32(iptr->sx.val.l))
2453 M_LCMP_IMM(iptr->sx.val.l, s1);
2455 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2456 M_LCMP(REG_ITMP2, s1);
2459 codegen_add_branch_ref(cd, iptr->dst.block);
2463 case ICMD_IF_LLT: /* ..., value ==> ... */
2467 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2468 if (IS_IMM32(iptr->sx.val.l))
2469 M_LCMP_IMM(iptr->sx.val.l, s1);
2471 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2472 M_LCMP(REG_ITMP2, s1);
2475 codegen_add_branch_ref(cd, iptr->dst.block);
2479 case ICMD_IF_LLE: /* ..., value ==> ... */
2483 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2484 if (IS_IMM32(iptr->sx.val.l))
2485 M_LCMP_IMM(iptr->sx.val.l, s1);
2487 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2488 M_LCMP(REG_ITMP2, s1);
2491 codegen_add_branch_ref(cd, iptr->dst.block);
2495 case ICMD_IF_LNE: /* ..., value ==> ... */
2499 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2500 if (IS_IMM32(iptr->sx.val.l))
2501 M_LCMP_IMM(iptr->sx.val.l, s1);
2503 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2504 M_LCMP(REG_ITMP2, s1);
2507 codegen_add_branch_ref(cd, iptr->dst.block);
2511 case ICMD_IF_LGT: /* ..., value ==> ... */
2515 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2516 if (IS_IMM32(iptr->sx.val.l))
2517 M_LCMP_IMM(iptr->sx.val.l, s1);
2519 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2520 M_LCMP(REG_ITMP2, s1);
2523 codegen_add_branch_ref(cd, iptr->dst.block);
2527 case ICMD_IF_LGE: /* ..., value ==> ... */
2531 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2532 if (IS_IMM32(iptr->sx.val.l))
2533 M_LCMP_IMM(iptr->sx.val.l, s1);
2535 M_MOV_IMM(iptr->sx.val.l, REG_ITMP2);
2536 M_LCMP(REG_ITMP2, s1);
2539 codegen_add_branch_ref(cd, iptr->dst.block);
2543 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2544 case ICMD_IF_ACMPEQ: /* op1 = target JavaVM pc */
2546 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2547 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2550 codegen_add_branch_ref(cd, iptr->dst.block);
2553 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
2555 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2556 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2558 /* load low-bits before the branch, so we know the distance */
2559 /* TODO do the loads modify the condition code?
2560 * lr, l, la, lhi dont
2562 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2563 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2564 M_BNE(SZ_BRC + SZ_CR + SZ_BRC);
2567 codegen_add_branch_ref(cd, iptr->dst.block);
2570 case ICMD_IF_ACMPNE: /* op1 = target JavaVM pc */
2571 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2573 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2574 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2577 codegen_add_branch_ref(cd, iptr->dst.block);
2581 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
2585 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2586 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2589 codegen_add_branch_ref(cd, iptr->dst.block);
2593 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2595 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2596 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2599 codegen_add_branch_ref(cd, iptr->dst.block);
2603 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
2607 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2608 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2611 codegen_add_branch_ref(cd, iptr->dst.block);
2615 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2617 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2618 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2621 codegen_add_branch_ref(cd, iptr->dst.block);
2625 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
2629 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2630 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2633 codegen_add_branch_ref(cd, iptr->dst.block);
2637 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2639 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2640 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2643 codegen_add_branch_ref(cd, iptr->dst.block);
2647 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
2649 s1 = emit_load_s1_high(jd, iptr, REG_ITMP1);
2650 s2 = emit_load_s2_high(jd, iptr, REG_ITMP2);
2653 codegen_add_branch_ref(cd, iptr->dst.block);
2654 /* load low-bits before the branch, so we know the distance */
2655 /* TODO: the loads should not touch the condition code. */
2656 s1 = emit_load_s1_low(jd, iptr, REG_ITMP1);
2657 s2 = emit_load_s2_low(jd, iptr, REG_ITMP2);
2658 M_BGT(SZ_BRC + SZ_CR + SZ_BRC);
2661 codegen_add_branch_ref(cd, iptr->dst.block);
2664 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2666 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2667 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2670 codegen_add_branch_ref(cd, iptr->dst.block);
2674 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
2678 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2679 s2 = emit_load_s2(jd, iptr, REG_ITMP2);
2682 codegen_add_branch_ref(cd, iptr->dst.block);
2686 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2688 REPLACEMENT_POINT_RETURN(cd, iptr);
2689 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2690 M_INTMOVE(s1, REG_RESULT);
2691 goto nowperformreturn;
2693 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2695 REPLACEMENT_POINT_RETURN(cd, iptr);
2696 s1 = emit_load_s1(jd, iptr, REG_RESULT);
2697 M_INTMOVE(s1, REG_RESULT);
2699 #ifdef ENABLE_VERIFIER
2700 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2701 unresolved_class *uc = iptr->sx.s23.s2.uc;
2703 codegen_addpatchref(cd, PATCHER_athrow_areturn, uc, 0);
2705 #endif /* ENABLE_VERIFIER */
2706 goto nowperformreturn;
2708 case ICMD_LRETURN: /* ..., retvalue ==> ... */
2710 REPLACEMENT_POINT_RETURN(cd, iptr);
2711 s1 = emit_load_s1(jd, iptr, REG_RESULT_PACKED);
2712 M_LNGMOVE(s1, REG_RESULT_PACKED);
2713 goto nowperformreturn;
2715 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2718 REPLACEMENT_POINT_RETURN(cd, iptr);
2719 s1 = emit_load_s1(jd, iptr, REG_FRESULT);
2720 M_FLTMOVE(s1, REG_FRESULT);
2721 goto nowperformreturn;
2723 case ICMD_RETURN: /* ... ==> ... */
2725 REPLACEMENT_POINT_RETURN(cd, iptr);
2731 p = cd->stackframesize;
2733 /* call trace function */
2735 #if !defined(NDEBUG)
2736 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
2737 emit_verbosecall_exit(jd);
2738 #endif /* !defined(NDEBUG) */
2740 #if defined(ENABLE_THREADS)
2741 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2742 disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
2743 M_ALD(REG_ITMP3, REG_PV, disp);
2746 /* we need to save the proper return value */
2748 switch (iptr->opc) {
2750 M_IST(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2754 M_IST(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2757 M_FST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2760 M_DST(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2764 M_ALD(REG_A0, REG_SP, rd->memuse * 4);
2767 /* and now restore the proper return value */
2769 switch (iptr->opc) {
2771 M_ILD(REG_RESULT2, REG_SP, rd->memuse * 4 + 8);
2775 M_ILD(REG_RESULT , REG_SP, rd->memuse * 4 + 4);
2778 M_FLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2781 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 4 + 4);
2787 /* restore return address */
2789 p--; M_ALD(REG_RA, REG_SP, p * 4);
2791 /* restore saved registers */
2793 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2794 p--; M_ILD(rd->savintregs[i], REG_SP, p * 4);
2796 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2797 p -= 2; M_DLD(rd->savfltregs[i], REG_SP, p * 4);
2800 /* deallocate stack */
2802 if (cd->stackframesize)
2803 M_AADD_IMM(cd->stackframesize * 4, REG_SP);
2810 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2815 branch_target_t *table;
2817 table = iptr->dst.table;
2819 l = iptr->sx.s23.s2.tablelow;
2820 i = iptr->sx.s23.s3.tablehigh;
2822 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2823 M_INTMOVE(s1, REG_ITMP1);
2826 M_ISUB_IMM(l, REG_ITMP1);
2828 /* number of targets */
2832 M_ICMP_IMM(i - 1, REG_ITMP1);
2835 codegen_add_branch_ref(cd, table[0].block); /* default target */
2837 /* build jump table top down and use address of lowest entry */
2842 dseg_add_target(cd, table->block);
2846 /* length of dataseg after last dseg_add_target is used
2849 M_MOV_IMM(0, REG_ITMP2);
2851 emit_mov_memindex_reg(cd, -(cd->dseglen), REG_ITMP2, REG_ITMP1, 3, REG_ITMP1);
2858 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
2863 lookup_target_t *lookup;
2865 lookup = iptr->dst.lookup;
2867 i = iptr->sx.s23.s2.lookupcount;
2869 MCODECHECK(8 + ((7 + 6) * i) + 5);
2870 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
2873 M_ICMP_IMM(lookup->value, s1);
2875 codegen_add_branch_ref(cd, lookup->target.block);
2881 codegen_add_branch_ref(cd, iptr->sx.s23.s3.lookupdefault.block);
2887 case ICMD_BUILTIN: /* ..., [arg1, [arg2 ...]] ==> ... */
2889 bte = iptr->sx.s23.s3.bte;
2893 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
2894 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
2895 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
2896 case ICMD_INVOKEINTERFACE:
2898 REPLACEMENT_POINT_INVOKE(cd, iptr);
2900 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2902 um = iptr->sx.s23.s3.um;
2903 md = um->methodref->parseddesc.md;
2906 lm = iptr->sx.s23.s3.fmiref->p.method;
2908 md = lm->parseddesc;
2912 s3 = md->paramcount;
2914 MCODECHECK((s3 << 1) + 64);
2916 /* copy arguments to registers or stack location */
2918 for (s3 = s3 - 1; s3 >= 0; s3--) {
2919 var = VAR(iptr->sx.s23.s2.args[s3]);
2921 /* Already Preallocated? */
2922 if (var->flags & PREALLOC)
2925 if (IS_INT_LNG_TYPE(var->type)) {
2926 if (!md->params[s3].inmemory) {
2927 if (IS_2_WORD_TYPE(var->type)) {
2929 rd->argintregs[GET_LOW_REG(md->params[s3].regoff)],
2930 rd->argintregs[GET_HIGH_REG(md->params[s3].regoff)]
2932 d = emit_load(jd, iptr, var, s1);
2936 s1 = rd->argintregs[md->params[s3].regoff];
2937 d = emit_load(jd, iptr, var, s1);
2942 if (IS_2_WORD_TYPE(var->type)) {
2943 d = emit_load(jd, iptr, var, REG_ITMP12_PACKED);
2944 M_LST(d, REG_SP, md->params[s3].regoff * 4);
2947 d = emit_load(jd, iptr, var, REG_ITMP1);
2948 M_IST(d, REG_SP, md->params[s3].regoff * 4);
2953 if (!md->params[s3].inmemory) {
2954 s1 = rd->argfltregs[md->params[s3].regoff];
2955 d = emit_load(jd, iptr, var, s1);
2959 d = emit_load(jd, iptr, var, REG_FTMP1);
2960 if (IS_2_WORD_TYPE(var->type))
2961 M_DST(d, REG_SP, md->params[s3].regoff * 4);
2963 M_FST(d, REG_SP, md->params[s3].regoff * 4);
2968 switch (iptr->opc) {
2970 disp = dseg_add_functionptr(cd, bte->fp);
2972 N_AHI(REG_SP, -96); /* register save area as required by C abi */
2973 N_LHI(REG_ITMP1, disp);
2974 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
2977 case ICMD_INVOKESPECIAL:
2978 emit_nullpointer_check(cd, iptr, REG_A0);
2979 M_ILD(REG_ITMP1, REG_A0, 0); /* hardware nullptr */
2982 case ICMD_INVOKESTATIC:
2984 disp = dseg_add_unique_address(cd, um);
2986 codegen_addpatchref(cd, PATCHER_invokestatic_special,
2990 disp = dseg_add_address(cd, lm->stubroutine);
2992 N_LHI(REG_ITMP1, disp);
2993 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
2996 case ICMD_INVOKEVIRTUAL:
2997 emit_nullpointer_check(cd, iptr, REG_A0);
3000 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3005 s1 = OFFSET(vftbl_t, table[0]) +
3006 sizeof(methodptr) * lm->vftblindex;
3009 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3010 M_ALD(REG_PV, REG_METHODPTR, s1);
3013 case ICMD_INVOKEINTERFACE:
3014 emit_nullpointer_check(cd, iptr, REG_A0);
3016 /* s1 will be negative here, so use (0xFFF + s1) as displacement
3017 * and -0xFFF in index register (itmp1)
3020 N_LHI(REG_ITMP1, -N_DISP_MAX);
3023 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3029 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3030 sizeof(methodptr*) * lm->class->index +
3033 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3036 M_ALD(REG_METHODPTR, REG_A0, OFFSET(java_objectheader, vftbl));
3037 N_L(REG_METHODPTR, s1, REG_ITMP1, REG_METHODPTR);
3038 M_ALD(REG_PV, REG_METHODPTR, s2);
3042 /* generate the actual call */
3045 REPLACEMENT_POINT_INVOKE_RETURN(cd, iptr);
3046 N_BASR(REG_ITMP1, RN);
3047 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3048 M_LDA(REG_PV, REG_ITMP1, -disp);
3050 /* post call finalization */
3052 if (iptr->opc == ICMD_BUILTIN) {
3053 N_AHI(REG_SP, 96); /* remove C abi register save area */
3056 /* actually only used for ICMD_BUILTIN */
3058 if (INSTRUCTION_MUST_CHECK(iptr)) {
3061 codegen_add_fillinstacktrace_ref(cd);
3064 /* store return value */
3066 d = md->returntype.type;
3068 if (d != TYPE_VOID) {
3069 if (IS_INT_LNG_TYPE(d)) {
3070 if (IS_2_WORD_TYPE(d)) {
3071 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT_PACKED);
3072 M_LNGMOVE(REG_RESULT_PACKED, s1);
3075 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3076 M_INTMOVE(REG_RESULT, s1);
3080 s1 = codegen_reg_of_dst(jd, iptr, REG_FRESULT);
3081 M_FLTMOVE(REG_FRESULT, s1);
3083 emit_store_dst(jd, iptr, s1);
3089 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3091 /* val.a: (classinfo*) superclass */
3093 /* superclass is an interface:
3095 * OK if ((sub == NULL) ||
3096 * (sub->vftbl->interfacetablelength > super->index) &&
3097 * (sub->vftbl->interfacetable[-super->index] != NULL));
3099 * superclass is a class:
3101 * OK if ((sub == NULL) || (0
3102 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3103 * super->vftbl->diffval));
3106 if (!(iptr->flags.bits & INS_FLAG_ARRAY)) {
3107 /* object type cast-check */
3110 vftbl_t *supervftbl;
3113 u1 *class_label_refs[] = { 0 }, *class_label;
3114 u1 *exit_label_refs[] = { 0, 0, 0, 0 };
3116 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3122 super = iptr->sx.s23.s3.c.cls;
3123 superindex = super->index;
3124 supervftbl = super->vftbl;
3127 #if defined(ENABLE_THREADS)
3128 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3130 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3132 /* if class is not resolved, check which code to call */
3134 if (super == NULL) {
3136 exit_label_refs[0] = cd->mcodeptr;
3139 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3141 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
3142 iptr->sx.s23.s3.c.ref,
3145 ICONST(REG_ITMP2, ACC_INTERFACE);
3146 ICONST(REG_ITMP3, disp); /* TODO negative displacement */
3147 N_N(REG_ITMP2, 0, REG_ITMP3, REG_PV);
3148 class_label_refs[0] = cd->mcodeptr;
3152 /* interface checkcast code */
3154 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3155 if (super == NULL) {
3156 codegen_add_patch_ref(cd,
3157 PATCHER_checkcast_instanceof_interface,
3158 iptr->sx.s23.s3.c.ref,
3162 exit_label_refs[1] = cd->mcodeptr;
3166 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3167 M_ILD(REG_ITMP3, REG_ITMP2,
3168 OFFSET(vftbl_t, interfacetablelength));
3169 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3172 codegen_add_classcastexception_ref(cd, s1);
3173 M_ALD(REG_ITMP3, REG_ITMP2,
3174 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3175 superindex * sizeof(methodptr*)));
3178 codegen_add_classcastexception_ref(cd, s1);
3180 if (super == NULL) {
3181 exit_label_refs[2] = cd->mcodeptr;
3186 /* class checkcast code */
3188 class_label = cd->mcodeptr;
3190 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3191 if (super == NULL) {
3192 disp = dseg_add_unique_address(cd, NULL);
3194 codegen_add_patch_ref(cd,
3195 PATCHER_resolve_classref_to_vftbl,
3196 iptr->sx.s23.s3.c.ref,
3200 disp = dseg_add_address(cd, supervftbl);
3202 exit_label_refs[3] = cd->mcodeptr;
3206 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3207 M_ALD(REG_ITMP3, REG_PV, disp);
3208 #if defined(ENABLE_THREADS)
3209 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3211 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3212 /* if (s1 != REG_ITMP1) { */
3213 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3214 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3215 /* #if defined(ENABLE_THREADS) */
3216 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3218 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3221 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3222 M_ISUB(REG_ITMP3, REG_ITMP2);
3223 M_ALD(REG_ITMP3, REG_PV, disp);
3224 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3225 #if defined(ENABLE_THREADS)
3226 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3229 N_CLR(REG_ITMP2, REG_ITMP3); /* Unsigned compare */
3230 /* M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3); itmp3 = (itmp2 <= itmp3) */
3231 M_BGT(0); /* Branch if greater then */
3232 /* M_BEQZ(REG_ITMP3, 0); branch if (! itmp) -> branch if > */
3233 codegen_add_classcastexception_ref(cd, s1);
3236 /* resolve labels by adding the correct displacement */
3238 for (s2 = 0; s2 < sizeof(exit_label_refs) / sizeof(exit_label_refs[0]); ++s2) {
3239 if (exit_label_refs[s2])
3240 *(u4 *)exit_label_refs[s2] |= (u4)(cd->mcodeptr - exit_label_refs[s2]) / 2;
3243 for (s2 = 0; s2 < sizeof(class_label_refs) / sizeof(class_label_refs[0]); ++s2) {
3244 if (class_label_refs[s2])
3245 *(u4 *)class_label_refs[s2] |= (u4)(class_label - class_label_refs[s2]) / 2;
3248 d = codegen_reg_of_dst(jd, iptr, s1);
3251 /* array type cast-check */
3253 s1 = emit_load_s1(jd, iptr, REG_A0);
3254 M_INTMOVE(s1, REG_A0);
3256 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3257 disp = dseg_add_unique_address(cd, NULL);
3259 codegen_add_patch_ref(cd,
3260 PATCHER_resolve_classref_to_classinfo,
3261 iptr->sx.s23.s3.c.ref,
3265 disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
3267 M_ALD(REG_A1, REG_PV, disp);
3268 disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
3269 ICONST(REG_ITMP1, disp); /* TODO negative displacement */
3270 N_L(REG_PV, 0, REG_ITMP1, REG_PV);
3271 M_JSR(REG_RA, REG_PV);
3272 N_BASR(REG_ITMP1, RN);
3273 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3274 M_LDA(REG_PV, REG_ITMP1, -disp);
3276 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3279 codegen_add_classcastexception_ref(cd, s1);
3281 d = codegen_reg_of_dst(jd, iptr, s1);
3285 emit_store_dst(jd, iptr, d);
3288 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3289 /* val.a: (classinfo*) superclass */
3291 /* superclass is an interface:
3293 * return (sub != NULL) &&
3294 * (sub->vftbl->interfacetablelength > super->index) &&
3295 * (sub->vftbl->interfacetable[-super->index] != NULL);
3297 * superclass is a class:
3299 * return ((sub != NULL) && (0
3300 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3301 * super->vftbl->diffvall));
3306 vftbl_t *supervftbl;
3309 u1 *class_label, *class_label_refs[1] = { 0 };
3310 u1 *exit_label_refs[4] = { 0, 0, 0, 0 };
3311 u1 *label1, *label1_refs[1] = { 0 };
3313 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3319 super = iptr->sx.s23.s3.c.cls;
3320 superindex = super->index;
3321 supervftbl = super->vftbl;
3324 #if defined(ENABLE_THREADS)
3325 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3327 s1 = emit_load_s1(jd, iptr, REG_ITMP1);
3328 d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
3330 M_MOV(s1, REG_ITMP1);
3334 /* if class is not resolved, check which code to call */
3336 if (super == NULL) {
3340 exit_label_refs[0] = cd->mcodeptr;
3343 disp = dseg_add_unique_s4(cd, 0); /* super->flags */
3345 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_flags,
3346 iptr->sx.s23.s3.c.ref, disp);
3348 ICONST(REG_ITMP2, ACC_INTERFACE);
3349 ICONST(REG_ITMP3, disp); /* TODO negative displacement */
3350 N_N(REG_ITMP2, 0, REG_ITMP3, REG_PV);
3351 class_label_refs[0] = cd->mcodeptr;
3355 /* interface instanceof code */
3357 if ((super == NULL) || (super->flags & ACC_INTERFACE)) {
3358 if (super == NULL) {
3359 /* If d == REG_ITMP2, then it's destroyed in check
3364 codegen_add_patch_ref(cd,
3365 PATCHER_checkcast_instanceof_interface,
3366 iptr->sx.s23.s3.c.ref, 0);
3371 exit_label_refs[1] = cd->mcodeptr;
3375 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3376 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3377 M_ASUB_IMM(superindex, REG_ITMP3);
3378 label1_refs[0] = cd->mcodeptr;
3382 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3383 superindex * sizeof(methodptr*))
3385 M_ALD(REG_ITMP1, REG_ITMP1, 0);
3387 /* d := (REG_ITMP1 != 0) */
3389 N_LTR(d, REG_ITMP1);
3393 label1 = cd->mcodeptr;
3395 if (super == NULL) {
3396 exit_label_refs[2] = cd->mcodeptr;
3401 /* class instanceof code */
3403 class_label = cd->mcodeptr;
3405 if ((super == NULL) || !(super->flags & ACC_INTERFACE)) {
3406 if (super == NULL) {
3407 disp = dseg_add_unique_address(cd, NULL);
3409 codegen_add_patch_ref(cd, PATCHER_resolve_classref_to_vftbl,
3410 iptr->sx.s23.s3.c.ref,
3414 disp = dseg_add_address(cd, supervftbl);
3419 exit_label_refs[3] = cd->mcodeptr;
3423 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3424 M_ALD(REG_ITMP2, REG_PV, disp);
3425 #if defined(ENABLE_THREADS)
3426 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3428 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3429 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3430 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3431 #if defined(ENABLE_THREADS)
3432 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3434 M_ISUB(REG_ITMP1, REG_ITMP3);
3436 N_CLR(REG_ITMP1, REG_ITMP2); /* d := (uint)REG_ITMP1 <= (uint)REG_ITMP2 */
3442 /* resolve labels by adding the correct displacement */
3444 for (s2 = 0; s2 < sizeof(exit_label_refs) / sizeof(exit_label_refs[0]); ++s2) {
3445 if (exit_label_refs[s2])
3446 *(u4 *)exit_label_refs[s2] |= (u4)(cd->mcodeptr - exit_label_refs[s2]) / 2;
3449 for (s2 = 0; s2 < sizeof(class_label_refs) / sizeof(class_label_refs[0]); ++s2) {
3450 if (class_label_refs[s2])
3451 *(u4 *)class_label_refs[s2] |= (u4)(class_label - class_label_refs[s2]) / 2;
3454 for (s2 = 0; s2 < sizeof(label1_refs) / sizeof(label1_refs[0]); ++s2) {
3455 if (label1_refs[s2])
3456 *(u4 *)label1_refs[s2] |= (u4)(label1 - label1_refs[s2]) / 2;
3459 emit_store_dst(jd, iptr, d);
3465 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3469 /* check for negative sizes and copy sizes to stack if necessary */
3471 MCODECHECK((10 * 4 * iptr->s1.argcount) + 5 + 10 * 8);
3473 for (s1 = iptr->s1.argcount; --s1 >= 0; ) {
3475 /* copy SAVEDVAR sizes to stack */
3476 var = VAR(iptr->sx.s23.s2.args[s1]);
3478 /* Already Preallocated? */
3479 if (!(var->flags & PREALLOC)) {
3480 s2 = emit_load(jd, iptr, var, REG_ITMP1);
3481 M_LST(s2, REG_SP, s1 * 8);
3485 /* is a patcher function set? */
3487 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3488 codegen_add_patch_ref(cd, PATCHER_builtin_multianewarray,
3489 iptr->sx.s23.s3.c.ref, 0);
3492 /* a0 = dimension count */
3494 M_MOV_IMM(iptr->s1.argcount, REG_A0);
3496 /* a1 = classinfo */
3498 M_MOV_IMM(iptr->sx.s23.s3.c.cls, REG_A1);
3500 /* a2 = pointer to dimensions = stack pointer */
3502 M_MOV(REG_SP, REG_A2);
3504 M_MOV_IMM(BUILTIN_multianewarray, REG_ITMP1);
3507 /* check for exception before result assignment */
3511 codegen_add_fillinstacktrace_ref(cd);
3513 s1 = codegen_reg_of_dst(jd, iptr, REG_RESULT);
3514 M_INTMOVE(REG_RESULT, s1);
3515 emit_store_dst(jd, iptr, s1);
3520 exceptions_throw_internalerror("Unknown ICMD %d", iptr->opc);
3524 } /* for instruction */
3526 MCODECHECK(512); /* XXX require a lower number? */
3528 /* At the end of a basic block we may have to append some nops,
3529 because the patcher stub calling code might be longer than the
3530 actual instruction. So codepatching does not change the
3531 following block unintentionally. */
3533 if (cd->mcodeptr < cd->lastmcodeptr) {
3534 while (cd->mcodeptr < cd->lastmcodeptr) {
3539 } /* if (bptr -> flags >= BBREACHED) */
3540 } /* for basic block */
3542 dseg_createlinenumbertable(cd);
3544 /* generate stubs */
3546 emit_exception_stubs(jd);
3547 emit_patcher_stubs(jd);
3549 emit_replacement_stubs(jd);
3554 /* everything's ok */
3560 /* createcompilerstub **********************************************************
3562 Creates a stub routine which calls the compiler.
3564 *******************************************************************************/
3566 #define COMPILERSTUB_DATASIZE (3 * SIZEOF_VOID_P)
3567 #define COMPILERSTUB_CODESIZE (SZ_AHI + SZ_L + SZ_L + SZ_BCR)
3569 #define COMPILERSTUB_SIZE (COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE)
3572 u1 *createcompilerstub(methodinfo *m)
3574 u1 *s; /* memory to hold the stub */
3580 s = CNEW(u1, COMPILERSTUB_SIZE);
3582 /* set data pointer and code pointer */
3585 s = s + COMPILERSTUB_DATASIZE;
3587 /* mark start of dump memory area */
3589 dumpsize = dump_size();
3591 cd = DNEW(codegendata);
3594 /* Store the codeinfo pointer in the same place as in the
3595 methodheader for compiled methods. */
3597 code = code_codeinfo_new(m);
3599 d[0] = (ptrint) asm_call_jit_compiler;
3601 d[2] = (ptrint) code;
3603 /* code for the stub */
3605 /* don't touch ITMP3 as it cointains the return address */
3607 M_ISUB_IMM((3 * 4), REG_PV); /* suppress negative displacements */
3609 M_ILD(REG_ITMP1, REG_PV, 1 * 4); /* methodinfo */
3610 /* TODO where is methodpointer loaded into itmp2? is it already inside? */
3611 M_ILD(REG_PV, REG_PV, 0 * 4); /* compiler pointer */
3614 #if defined(ENABLE_STATISTICS)
3616 count_cstub_len += COMPILERSTUB_SIZE;
3619 /* release dump area */
3621 dump_release(dumpsize);
3627 /* createnativestub ************************************************************
3629 Creates a stub routine which calls a native method.
3631 *******************************************************************************/
3634 arguments on stack \
3635 -------------------------------------------------| <- SP on nativestub entry
3637 callee saved int regs (none) |
3638 callee saved float regs (none) | stack frame like in cacao
3639 local variable slots (none) |
3640 arguments for calling methods (none) /
3641 ------------------------------------------------------------------ <- datasp
3646 96 - ... on stack parameters (nmd->memuse slots) \ stack frame like in ABI
3647 0 - 96 register save area for callee /
3648 -------------------------------------------------------- <- SP native method
3650 SP after method entry
3653 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
3661 s4 i, j; /* count variables */
3666 /* get required compiler data */
3673 /* initialize variables */
3676 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
3678 /* calculate stack frame size */
3680 cd->stackframesize =
3681 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3682 sizeof(localref_table) / SIZEOF_VOID_P +
3683 INT_ARG_CNT + FLT_ARG_CNT +
3684 1 + /* functionptr, TODO: store in data segment */
3687 cd->stackframesize |= 0x1; /* keep stack 16-byte aligned */
3690 cd->stackframesize =
3691 1 + /* r14 - return address */ +
3692 sizeof(stackframeinfo) / SIZEOF_VOID_P +
3693 sizeof(localref_table) / SIZEOF_VOID_P +
3695 (INT_ARG_CNT + FLT_ARG_CNT) * 2 +
3696 nmd->memuse + /* parameter passing */
3697 96 / SIZEOF_VOID_P /* required by ABI */;
3699 cd->stackframesize |= 0x1; /* keep stack 8-byte aligned */
3702 /* create method header */
3704 (void) dseg_add_unique_address(cd, code); /* CodeinfoPointer */
3705 (void) dseg_add_unique_s4(cd, cd->stackframesize * 4); /* FrameSize */
3706 (void) dseg_add_unique_s4(cd, 0); /* IsSync */
3707 (void) dseg_add_unique_s4(cd, 0); /* IsLeaf */
3708 (void) dseg_add_unique_s4(cd, 0); /* IntSave */
3709 (void) dseg_add_unique_s4(cd, 0); /* FltSave */
3710 (void) dseg_addlinenumbertablesize(cd);
3711 (void) dseg_add_unique_s4(cd, 0); /* ExTableSize */
3713 /* generate native method profiling code */
3715 if (JITDATA_HAS_FLAG_INSTRUMENT(jd)) {
3716 /* count frequency */
3718 M_MOV_IMM(code, REG_ITMP3);
3719 M_IINC_MEMBASE(REG_ITMP3, OFFSET(codeinfo, frequency));
3723 /* generate stub code */
3725 N_AHI(REG_SP, -(cd->stackframesize * SIZEOF_VOID_P));
3727 /* save return address */
3729 N_ST(R14, (cd->stackframesize - 1) * SIZEOF_VOID_P, RN, REG_SP);
3732 #if !defined(NDEBUG)
3733 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3734 emit_verbosecall_enter(jd);
3738 /* get function address (this must happen before the stackframeinfo) */
3740 disp = dseg_add_functionptr(cd, f);
3742 #if !defined(WITH_STATIC_CLASSPATH)
3744 codegen_add_patch_ref(cd, PATCHER_resolve_native, m, disp);
3747 M_ILD(REG_ITMP1, REG_PV, disp);
3749 j = 96 + (nmd->memuse * 4);
3751 /* todo some arg registers are not volatile in C-abi terms */
3753 /* save integer and float argument registers */
3755 for (i = 0; i < md->paramcount; i++) {
3756 if (! md->params[i].inmemory) {
3757 s1 = md->params[i].regoff;
3759 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3760 if (IS_2_WORD_TYPE(t)) {
3761 /* todo store multiple */
3762 N_ST(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3763 N_ST(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3765 N_ST(rd->argintregs[s1], j, RN, REG_SP);
3768 if (IS_2_WORD_TYPE(t)) {
3769 N_STD(rd->argfltregs[s1], j, RN, REG_SP);
3771 N_STE(rd->argfltregs[s1], j, RN, REG_SP);
3779 N_ST(REG_ITMP1, j, RN, REG_SP);
3781 /* create dynamic stack info */
3783 N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
3784 N_LR(REG_A1, REG_PV); /* pv */
3785 N_LAE(REG_A2, cd->stackframesize * 4, RN, REG_SP); /* old SP */
3786 N_L(REG_A3, (cd->stackframesize - 1) * 4, RN, REG_SP); /* return address */
3788 disp = dseg_add_functionptr(cd, codegen_start_native_call);
3789 M_ILD(REG_ITMP1, REG_PV, disp);
3791 M_CALL(REG_ITMP1); /* call */
3793 /* restore integer and float argument registers */
3795 j = 96 + (nmd->memuse * 4);
3797 for (i = 0; i < md->paramcount; i++) {
3798 if (! md->params[i].inmemory) {
3799 s1 = md->params[i].regoff;
3801 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
3802 if (IS_2_WORD_TYPE(t)) {
3803 /* todo load multiple ! */
3804 N_L(rd->argintregs[GET_HIGH_REG(s1)], j, RN, REG_SP);
3805 N_L(rd->argintregs[GET_LOW_REG(s1)], j + 4, RN, REG_SP);
3807 N_L(rd->argintregs[s1], j, RN, REG_SP);
3810 if (IS_2_WORD_TYPE(t)) {
3811 N_LD(rd->argfltregs[s1], j, RN, REG_SP);
3813 N_LE(rd->argfltregs[s1], j, RN, REG_SP);
3821 N_L(REG_ITMP1, j, RN, REG_SP);
3823 /* copy or spill arguments to new locations */
3825 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
3826 t = md->paramtypes[i].type;
3828 if (IS_INT_LNG_TYPE(t)) {
3830 if (!md->params[i].inmemory) {
3832 s1 = rd->argintregs[md->params[i].regoff];
3834 if (!nmd->params[j].inmemory) {
3835 s2 = rd->argintregs[nmd->params[j].regoff];
3836 if (IS_2_WORD_TYPE(t)) {
3837 N_LR(GET_HIGH_REG(s2), GET_HIGH_REG(s1));
3838 N_LR(GET_LOW_REG(s2), GET_LOW_REG(s1));
3843 s2 = nmd->params[j].regoff;
3844 if (IS_2_WORD_TYPE(t)) {
3845 N_STM(GET_LOW_REG(s1), GET_HIGH_REG(s1), 96 + (s2 * 4), REG_SP);
3847 N_ST(s1, 96 + (s2 * 4), RN, REG_SP);
3852 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3853 s2 = nmd->params[j].regoff;
3855 if (IS_2_WORD_TYPE(t)) {
3856 N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3858 N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3863 /* We only copy spilled float arguments, as the float argument */
3864 /* registers keep unchanged. */
3866 if (md->params[i].inmemory) {
3867 s1 = md->params[i].regoff + cd->stackframesize + 1; /* + 1 (RA) */
3868 s2 = nmd->params[j].regoff;
3870 if (IS_2_WORD_TYPE(t)) {
3871 N_MVC(96 + (s2 * 4), 8, REG_SP, s1, REG_SP);
3873 N_MVC(96 + (s2 * 4), 4, REG_SP, s1, REG_SP);
3879 /* put class into second argument register */
3881 if (m->flags & ACC_STATIC) {
3882 disp = dseg_add_address(cd, m->class);
3883 M_ILD(REG_A1, REG_PV, disp);
3886 /* put env into first argument register */
3888 disp = dseg_add_address(cd, _Jv_env);
3889 M_ILD(REG_A0, REG_PV, disp);
3891 /* do the native function call */
3893 M_CALL(REG_ITMP1); /* call */
3895 /* save return value */
3897 t = md->returntype.type;
3899 if (t != TYPE_VOID) {
3900 if (IS_INT_LNG_TYPE(t)) {
3901 if (IS_2_WORD_TYPE(t)) {
3902 N_STM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3904 N_ST(REG_RESULT, 96, RN, REG_SP);
3907 if (IS_2_WORD_TYPE(t)) {
3908 N_STD(REG_FRESULT, 96, RN, REG_SP);
3910 N_STE(REG_FRESULT, 96, RN, REG_SP);
3916 #if !defined(NDEBUG)
3917 if (JITDATA_HAS_FLAG_VERBOSECALL(jd))
3918 emit_verbosecall_exit(jd);
3922 /* remove native stackframe info */
3924 N_LAE(REG_A0, (cd->stackframesize - 1) * 4, RN, REG_SP); /* datasp */
3925 disp = dseg_add_functionptr(cd, codegen_finish_native_call);
3926 M_ILD(REG_ITMP1, REG_PV, disp);
3928 N_LR(REG_ITMP3, REG_RESULT);
3930 /* restore return value */
3932 if (t != TYPE_VOID) {
3933 if (IS_INT_LNG_TYPE(t)) {
3934 if (IS_2_WORD_TYPE(t)) {
3935 N_LM(REG_RESULT, REG_RESULT2, 96, REG_SP);
3937 N_L(REG_RESULT, 96, RN, REG_SP);
3940 if (IS_2_WORD_TYPE(t)) {
3941 N_LD(REG_FRESULT, 96, RN, REG_SP);
3943 N_LE(REG_FRESULT, 96, RN, REG_SP);
3948 /* load return address */
3950 N_L(REG_ITMP2, (cd->stackframesize - 1) * 4, RN, REG_SP);
3952 /* remove stackframe */
3954 N_AHI(REG_SP, cd->stackframesize * 4);
3956 /* test for exception */
3958 N_LTR(REG_ITMP3, REG_ITMP3);
3959 N_BRC(DD_NE, SZ_BRC + SZ_BCR);
3963 N_BCR(DD_ANY, REG_ITMP2);
3965 /* handle exception */
3967 M_MOV(REG_ITMP3, REG_ITMP1_XPTR);
3968 M_ALD(REG_ITMP2_XPC, REG_SP, (cd->stackframesize - 1) * 4); /* get return address from stack */
3971 M_ASUB_IMM(3, REG_ITMP2_XPC); /* callq */
3973 disp = dseg_add_functionptr(cd, /*asm_handle_nat_exception*/ panic);
3975 M_ALD(REG_ITMP3, REG_PV, disp);
3976 M_JMP(RN, REG_ITMP3);
3978 /* generate patcher stubs */
3980 emit_patcher_stubs(jd);
3984 return code->entrypoint;
3988 s4 codegen_reg_of_dst_notzero(jitdata *jd, instruction *iptr, s4 tempregnum) {
3989 codegendata *cd = jd->cd;
3990 s4 reg = codegen_reg_of_dst(jd, iptr, tempregnum);
3992 M_MOV(reg, tempregnum);
4000 * These are local overrides for various environment variables in Emacs.
4001 * Please do not remove this and leave it at the end of the file, where
4002 * Emacs will automagically detect them.
4003 * ---------------------------------------------------------------------
4006 * indent-tabs-mode: t
4010 * vim:noexpandtab:sw=4:ts=4: