1 /* src/vm/jit/mips/codegen.c - machine code generator for MIPS
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
30 Changes: Christian Thalinger
34 Contains the codegenerator for an MIPS (R4000 or higher) processor.
35 This module generates MIPS machine code for a sequence of
36 intermediate code commands (ICMDs).
38 $Id: codegen.c 5043 2006-06-20 15:50:58Z twisti $
53 #include "vm/jit/mips/arch.h"
54 #include "vm/jit/mips/codegen.h"
56 #include "native/native.h"
57 #include "vm/builtin.h"
59 #include "vm/exceptions.h"
60 #include "vm/options.h"
61 #include "vm/stringlocal.h"
63 #include "vm/jit/asmpart.h"
64 #include "vm/jit/codegen-common.h"
65 #include "vm/jit/dseg.h"
66 #include "vm/jit/emit.h"
67 #include "vm/jit/jit.h"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/replace.h"
72 #if defined(ENABLE_LSRA)
73 # include "vm/jit/allocator/lsra.h"
77 /* codegen *********************************************************************
79 Generates machine code.
81 *******************************************************************************/
83 bool codegen(jitdata *jd)
89 s4 len, s1, s2, s3, d, disp;
98 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
99 builtintable_entry *bte;
101 rplpoint *replacementpoint;
103 /* get required compiler data */
114 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
116 /* space to save used callee saved registers */
118 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
119 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
121 parentargs_base = rd->memuse + savedregs_num;
123 #if defined(ENABLE_THREADS)
124 /* space to save argument of monitor_enter */
126 if (checksync && (m->flags & ACC_SYNCHRONIZED))
130 /* adjust frame size for 16 byte alignment */
132 if (parentargs_base & 1)
135 /* create method header */
137 #if SIZEOF_VOID_P == 4
138 (void) dseg_addaddress(cd, code); /* Filler */
140 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
141 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
143 #if defined(ENABLE_THREADS)
144 /* IsSync contains the offset relative to the stack pointer for the
145 argument of monitor_exit used in the exception handler. Since the
146 offset could be zero and give a wrong meaning of the flag it is
150 if (checksync && (m->flags & ACC_SYNCHRONIZED))
151 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
154 (void) dseg_adds4(cd, 0); /* IsSync */
156 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
157 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
158 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
159 dseg_addlinenumbertablesize(cd);
160 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
162 /* create exception table */
164 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
165 dseg_addtarget(cd, ex->start);
166 dseg_addtarget(cd, ex->end);
167 dseg_addtarget(cd, ex->handler);
168 (void) dseg_addaddress(cd, ex->catchtype.cls);
171 /* create stack frame (if necessary) */
174 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
176 /* save return address and used callee saved registers */
179 if (!m->isleafmethod) {
180 p--; M_AST(REG_RA, REG_SP, p * 8);
182 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
183 p--; M_AST(rd->savintregs[i], REG_SP, p * 8);
185 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
186 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
189 /* take arguments out of register or stack frame */
193 for (p = 0, l = 0; p < md->paramcount; p++) {
194 t = md->paramtypes[p].type;
195 var = &(rd->locals[l][t]);
197 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
201 s1 = md->params[p].regoff;
202 if (IS_INT_LNG_TYPE(t)) { /* integer args */
203 if (!md->params[p].inmemory) { /* register arguments */
204 s2 = rd->argintregs[s1];
205 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
206 M_INTMOVE(s2, var->regoff);
207 } else { /* reg arg -> spilled */
208 M_LST(s2, REG_SP, var->regoff * 8);
211 } else { /* stack arguments */
212 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
213 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
214 } else { /* stack arg -> spilled */
215 var->regoff = parentargs_base + s1;
219 } else { /* floating args */
220 if (!md->params[p].inmemory) { /* register arguments */
221 s2 = rd->argfltregs[s1];
222 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
223 if (IS_2_WORD_TYPE(t))
224 M_DMOV(s2, var->regoff);
226 M_FMOV(s2, var->regoff);
227 } else { /* reg arg -> spilled */
228 if (IS_2_WORD_TYPE(t))
229 M_DST(s2, REG_SP, var->regoff * 8);
231 M_FST(s2, REG_SP, var->regoff * 8);
234 } else { /* stack arguments */
235 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
236 if (IS_2_WORD_TYPE(t))
237 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
239 M_FLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
240 } else /* stack-arg -> spilled */
241 var->regoff = parentargs_base + s1;
246 /* call monitorenter function */
248 #if defined(ENABLE_THREADS)
249 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
250 /* stack offset for monitor argument */
254 if (opt_verbosecall) {
255 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
257 for (p = 0; p < INT_ARG_CNT; p++)
258 M_LST(rd->argintregs[p], REG_SP, p * 8);
260 for (p = 0; p < FLT_ARG_CNT; p++)
261 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
263 s1 += INT_ARG_CNT + FLT_ARG_CNT;
266 /* decide which monitor enter function to call */
268 if (m->flags & ACC_STATIC) {
269 p = dseg_addaddress(cd, m->class);
270 M_ALD(rd->argintregs[0], REG_PV, p);
271 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
272 M_ALD(REG_ITMP3, REG_PV, p);
273 M_JSR(REG_RA, REG_ITMP3);
274 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
277 M_BEQZ(rd->argintregs[0], 0);
278 codegen_add_nullpointerexception_ref(cd);
279 p = dseg_addaddress(cd, BUILTIN_monitorenter);
280 M_ALD(REG_ITMP3, REG_PV, p);
281 M_JSR(REG_RA, REG_ITMP3);
282 M_AST(rd->argintregs[0], REG_SP, s1 * 8); /* branch delay */
285 if (opt_verbosecall) {
286 for (p = 0; p < INT_ARG_CNT; p++)
287 M_LLD(rd->argintregs[p], REG_SP, p * 8);
289 for (p = 0; p < FLT_ARG_CNT; p++)
290 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
293 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
298 /* copy argument registers to stack and call trace function */
300 if (opt_verbosecall) {
301 M_LDA(REG_SP, REG_SP, -(2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
302 M_AST(REG_RA, REG_SP, 1 * 8);
304 /* save integer argument registers */
306 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
307 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
309 /* save and copy float arguments into integer registers */
311 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
312 t = md->paramtypes[p].type;
314 if (IS_FLT_DBL_TYPE(t)) {
315 if (IS_2_WORD_TYPE(t)) {
316 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
317 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
320 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
321 M_ILD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
325 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
329 /* save temporary registers for leaf methods */
331 if (m->isleafmethod) {
332 for (p = 0; p < INT_TMP_CNT; p++)
333 M_LST(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
335 for (p = 0; p < FLT_TMP_CNT; p++)
336 M_DST(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
339 p = dseg_addaddress(cd, m);
340 M_ALD(REG_ITMP1, REG_PV, p);
341 M_AST(REG_ITMP1, REG_SP, 0 * 8);
342 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
343 M_ALD(REG_ITMP3, REG_PV, disp);
344 M_JSR(REG_RA, REG_ITMP3);
347 M_ALD(REG_RA, REG_SP, 1 * 8);
349 /* restore integer argument registers */
351 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
352 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
354 /* restore float argument registers */
356 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
357 t = md->paramtypes[p].type;
359 if (IS_FLT_DBL_TYPE(t)) {
360 if (IS_2_WORD_TYPE(t)) {
361 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
364 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
368 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
372 /* restore temporary registers for leaf methods */
374 if (m->isleafmethod) {
375 for (p = 0; p < INT_TMP_CNT; p++)
376 M_LLD(rd->tmpintregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + p) * 8);
378 for (p = 0; p < FLT_TMP_CNT; p++)
379 M_DLD(rd->tmpfltregs[p], REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + p) * 8);
382 M_LDA(REG_SP, REG_SP, (2 + INT_ARG_CNT + FLT_ARG_CNT + INT_TMP_CNT + FLT_TMP_CNT) * 8);
387 /* end of header generation */
389 replacementpoint = jd->code->rplpoints;
391 /* walk through all basic blocks */
393 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
395 /* handle replacement points */
397 if (bptr->bitflags & BBFLAG_REPLACEMENT && bptr->flags >= BBREACHED) {
399 /* 8-byte align pc */
400 if ((ptrint) cd->mcodeptr & 4) {
404 replacementpoint->pc = (u1*)(ptrint) (cd->mcodeptr - cd->mcodebase);
407 assert(cd->lastmcodeptr <= cd->mcodeptr);
408 cd->lastmcodeptr = cd->mcodeptr + 2 * 4; /* br + delay slot */
411 /* store relative start of block */
413 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
415 if (bptr->flags >= BBREACHED) {
417 /* branch resolving */
420 for (bref = bptr->branchrefs; bref != NULL; bref = bref->next) {
421 gen_resolvebranch(cd->mcodebase + bref->branchpos,
427 /* copy interface registers to their destination */
432 #if defined(ENABLE_LSRA)
434 while (src != NULL) {
436 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
437 /* d = reg_of_var(m, src, REG_ITMP1); */
438 if (!(src->flags & INMEMORY))
442 M_INTMOVE(REG_ITMP1, d);
443 emit_store(jd, NULL, src, d);
449 while (src != NULL) {
451 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
452 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
453 M_INTMOVE(REG_ITMP1, d);
454 emit_store(jd, NULL, src, d);
457 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
458 if ((src->varkind != STACKVAR)) {
460 s1 = rd->interfaces[len][s2].regoff;
461 if (IS_FLT_DBL_TYPE(s2)) {
462 if (rd->interfaces[len][s2].flags & INMEMORY) {
463 if (IS_2_WORD_TYPE(s2))
464 M_DLD(d, REG_SP, s1 * 8);
466 M_FLD(d, REG_SP, s1 * 8);
469 if (IS_2_WORD_TYPE(s2))
476 if (rd->interfaces[len][s2].flags & INMEMORY)
477 M_LLD(d, REG_SP, s1 * 8);
482 emit_store(jd, NULL, src, d);
487 #if defined(ENABLE_LSRA)
490 /* walk through all instructions */
496 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
497 if (iptr->line != currentline) {
498 dseg_addlinenumber(cd, iptr->line);
499 currentline = iptr->line;
502 MCODECHECK(64); /* an instruction usually needs < 64 words */
506 case ICMD_NOP: /* ... ==> ... */
509 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
511 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
513 codegen_add_nullpointerexception_ref(cd);
517 /* constant operations ************************************************/
519 case ICMD_ICONST: /* ... ==> ..., constant */
520 /* op1 = 0, val.i = constant */
522 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
523 ICONST(d, iptr->val.i);
524 emit_store(jd, iptr, iptr->dst, d);
527 case ICMD_LCONST: /* ... ==> ..., constant */
528 /* op1 = 0, val.l = constant */
530 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
531 LCONST(d, iptr->val.l);
532 emit_store(jd, iptr, iptr->dst, d);
535 case ICMD_FCONST: /* ... ==> ..., constant */
536 /* op1 = 0, val.f = constant */
538 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
539 disp = dseg_addfloat(cd, iptr->val.f);
540 M_FLD(d, REG_PV, disp);
541 emit_store(jd, iptr, iptr->dst, d);
544 case ICMD_DCONST: /* ... ==> ..., constant */
545 /* op1 = 0, val.d = constant */
547 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
548 disp = dseg_adddouble(cd, iptr->val.d);
549 M_DLD(d, REG_PV, disp);
550 emit_store(jd, iptr, iptr->dst, d);
553 case ICMD_ACONST: /* ... ==> ..., constant */
554 /* op1 = 0, val.a = constant */
556 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
558 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
559 disp = dseg_addaddress(cd, NULL);
561 codegen_addpatchref(cd, PATCHER_aconst,
562 ICMD_ACONST_UNRESOLVED_CLASSREF(iptr),
565 if (opt_showdisassemble) {
569 M_ALD(d, REG_PV, disp);
572 if (iptr->val.a == NULL) {
573 M_INTMOVE(REG_ZERO, d);
575 disp = dseg_addaddress(cd, iptr->val.a);
576 M_ALD(d, REG_PV, disp);
579 emit_store(jd, iptr, iptr->dst, d);
583 /* load/store operations **********************************************/
585 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
586 /* op1 = local variable */
588 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
589 if ((iptr->dst->varkind == LOCALVAR) &&
590 (iptr->dst->varnum == iptr->op1))
592 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
593 if (var->flags & INMEMORY)
594 #if SIZEOF_VOID_P == 8
595 M_LLD(d, REG_SP, var->regoff * 8);
597 M_ILD(d, REG_SP, var->regoff * 8);
600 M_INTMOVE(var->regoff,d);
601 emit_store(jd, iptr, iptr->dst, d);
604 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
605 /* op1 = local variable */
607 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
608 if ((iptr->dst->varkind == LOCALVAR) &&
609 (iptr->dst->varnum == iptr->op1))
611 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
612 if (var->flags & INMEMORY)
613 M_LLD(d, REG_SP, var->regoff * 8);
615 M_INTMOVE(var->regoff,d);
616 emit_store(jd, iptr, iptr->dst, d);
619 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
620 /* op1 = local variable */
622 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
623 if ((iptr->dst->varkind == LOCALVAR) &&
624 (iptr->dst->varnum == iptr->op1))
626 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
627 if (var->flags & INMEMORY)
628 M_ALD(d, REG_SP, var->regoff * 8);
630 M_INTMOVE(var->regoff,d);
631 emit_store(jd, iptr, iptr->dst, d);
634 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
635 /* op1 = local variable */
637 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
638 if ((iptr->dst->varkind == LOCALVAR) &&
639 (iptr->dst->varnum == iptr->op1))
641 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
642 if (var->flags & INMEMORY)
643 M_FLD(d, REG_SP, var->regoff * 8);
645 M_FMOV(var->regoff, d);
646 emit_store(jd, iptr, iptr->dst, d);
649 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
650 /* op1 = local variable */
652 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
653 if ((iptr->dst->varkind == LOCALVAR) &&
654 (iptr->dst->varnum == iptr->op1))
656 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
657 if (var->flags & INMEMORY)
658 M_DLD(d, REG_SP, var->regoff * 8);
660 M_DMOV(var->regoff, d);
661 emit_store(jd, iptr, iptr->dst, d);
665 case ICMD_ISTORE: /* ..., value ==> ... */
666 /* op1 = local variable */
668 if ((src->varkind == LOCALVAR) &&
669 (src->varnum == iptr->op1))
671 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
672 if (var->flags & INMEMORY) {
673 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
674 #if SIZEOF_VOID_P == 8
675 M_LST(s1, REG_SP, var->regoff * 8);
677 M_IST(s1, REG_SP, var->regoff * 8);
680 s1 = emit_load_s1(jd, iptr, src, var->regoff);
681 M_INTMOVE(s1, var->regoff);
685 case ICMD_LSTORE: /* ..., value ==> ... */
686 /* op1 = local variable */
688 if ((src->varkind == LOCALVAR) &&
689 (src->varnum == iptr->op1))
691 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
692 if (var->flags & INMEMORY) {
693 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
694 M_LST(s1, REG_SP, var->regoff * 8);
696 s1 = emit_load_s1(jd, iptr, src, var->regoff);
697 M_INTMOVE(s1, var->regoff);
701 case ICMD_ASTORE: /* ..., value ==> ... */
702 /* op1 = local variable */
704 if ((src->varkind == LOCALVAR) &&
705 (src->varnum == iptr->op1))
707 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
708 if (var->flags & INMEMORY) {
709 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
710 M_AST(s1, REG_SP, var->regoff * 8);
712 s1 = emit_load_s1(jd, iptr, src, var->regoff);
713 M_INTMOVE(s1, var->regoff);
717 case ICMD_FSTORE: /* ..., value ==> ... */
718 /* op1 = local variable */
720 if ((src->varkind == LOCALVAR) &&
721 (src->varnum == iptr->op1))
723 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
724 if (var->flags & INMEMORY) {
725 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
726 M_FST(s1, REG_SP, var->regoff * 8);
728 s1 = emit_load_s1(jd, iptr, src, var->regoff);
729 M_FMOV(s1, var->regoff);
733 case ICMD_DSTORE: /* ..., value ==> ... */
734 /* op1 = local variable */
736 if ((src->varkind == LOCALVAR) &&
737 (src->varnum == iptr->op1))
739 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
740 if (var->flags & INMEMORY) {
741 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
742 M_DST(s1, REG_SP, var->regoff * 8);
744 s1 = emit_load_s1(jd, iptr, src, var->regoff);
745 M_DMOV(s1, var->regoff);
750 /* pop/dup/swap operations ********************************************/
752 /* attention: double and longs are only one entry in CACAO ICMDs */
754 case ICMD_POP: /* ..., value ==> ... */
755 case ICMD_POP2: /* ..., value, value ==> ... */
758 case ICMD_DUP: /* ..., a ==> ..., a, a */
759 M_COPY(src, iptr->dst);
762 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
764 M_COPY(src, iptr->dst);
765 M_COPY(src->prev, iptr->dst->prev);
766 M_COPY(iptr->dst, iptr->dst->prev->prev);
769 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
771 M_COPY(src, iptr->dst);
772 M_COPY(src->prev, iptr->dst->prev);
773 M_COPY(src->prev->prev, iptr->dst->prev->prev);
774 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
777 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
779 M_COPY(src, iptr->dst);
780 M_COPY(src->prev, iptr->dst->prev);
783 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
785 M_COPY(src, iptr->dst);
786 M_COPY(src->prev, iptr->dst->prev);
787 M_COPY(src->prev->prev, iptr->dst->prev->prev);
788 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
789 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
792 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
794 M_COPY(src, iptr->dst);
795 M_COPY(src->prev, iptr->dst->prev);
796 M_COPY(src->prev->prev, iptr->dst->prev->prev);
797 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
798 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
799 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
802 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
804 M_COPY(src, iptr->dst->prev);
805 M_COPY(src->prev, iptr->dst);
809 /* integer operations *************************************************/
811 case ICMD_INEG: /* ..., value ==> ..., - value */
813 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
814 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
815 M_ISUB(REG_ZERO, s1, d);
816 emit_store(jd, iptr, iptr->dst, d);
819 case ICMD_LNEG: /* ..., value ==> ..., - value */
821 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
822 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
823 M_LSUB(REG_ZERO, s1, d);
824 emit_store(jd, iptr, iptr->dst, d);
827 case ICMD_I2L: /* ..., value ==> ..., value */
829 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
830 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
832 emit_store(jd, iptr, iptr->dst, d);
835 case ICMD_L2I: /* ..., value ==> ..., value */
837 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
838 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
839 M_ISLL_IMM(s1, 0, d );
840 emit_store(jd, iptr, iptr->dst, d);
843 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
845 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
846 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
847 M_LSLL_IMM(s1, 56, d);
848 M_LSRA_IMM( d, 56, d);
849 emit_store(jd, iptr, iptr->dst, d);
852 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
854 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
855 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
857 emit_store(jd, iptr, iptr->dst, d);
860 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
862 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
863 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
864 M_LSLL_IMM(s1, 48, d);
865 M_LSRA_IMM( d, 48, d);
866 emit_store(jd, iptr, iptr->dst, d);
870 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
872 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
873 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
874 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
876 emit_store(jd, iptr, iptr->dst, d);
879 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
880 /* val.i = constant */
882 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
883 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
884 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
885 M_IADD_IMM(s1, iptr->val.i, d);
887 ICONST(REG_ITMP2, iptr->val.i);
888 M_IADD(s1, REG_ITMP2, d);
890 emit_store(jd, iptr, iptr->dst, d);
893 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
895 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
896 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
897 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
899 emit_store(jd, iptr, iptr->dst, d);
902 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
903 /* val.l = constant */
905 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
906 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
907 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
908 M_LADD_IMM(s1, iptr->val.l, d);
910 LCONST(REG_ITMP2, iptr->val.l);
911 M_LADD(s1, REG_ITMP2, d);
913 emit_store(jd, iptr, iptr->dst, d);
916 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
918 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
919 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
920 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
922 emit_store(jd, iptr, iptr->dst, d);
925 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
926 /* val.i = constant */
928 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
929 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
930 if ((iptr->val.i >= -32767) && (iptr->val.i <= 32768)) {
931 M_IADD_IMM(s1, -iptr->val.i, d);
933 ICONST(REG_ITMP2, iptr->val.i);
934 M_ISUB(s1, REG_ITMP2, d);
936 emit_store(jd, iptr, iptr->dst, d);
939 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
941 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
942 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
943 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
945 emit_store(jd, iptr, iptr->dst, d);
948 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
949 /* val.l = constant */
951 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
952 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
953 if ((iptr->val.l >= -32767) && (iptr->val.l <= 32768)) {
954 M_LADD_IMM(s1, -iptr->val.l, d);
956 LCONST(REG_ITMP2, iptr->val.l);
957 M_LSUB(s1, REG_ITMP2, d);
959 emit_store(jd, iptr, iptr->dst, d);
962 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
964 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
965 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
966 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
971 emit_store(jd, iptr, iptr->dst, d);
974 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
975 /* val.i = constant */
977 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
978 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
979 ICONST(REG_ITMP2, iptr->val.i);
980 M_IMUL(s1, REG_ITMP2);
984 emit_store(jd, iptr, iptr->dst, d);
987 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
989 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
990 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
991 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
996 emit_store(jd, iptr, iptr->dst, d);
999 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
1000 /* val.l = constant */
1002 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1003 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1004 LCONST(REG_ITMP2, iptr->val.l);
1005 M_LMUL(s1, REG_ITMP2);
1009 emit_store(jd, iptr, iptr->dst, d);
1012 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1014 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1015 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1016 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1022 emit_store(jd, iptr, iptr->dst, d);
1025 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1027 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1028 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1029 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1035 emit_store(jd, iptr, iptr->dst, d);
1038 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1040 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1041 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1042 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1048 emit_store(jd, iptr, iptr->dst, d);
1051 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1053 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1054 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1055 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1061 emit_store(jd, iptr, iptr->dst, d);
1064 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
1065 case ICMD_LDIVPOW2: /* val.i = constant */
1067 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1068 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1069 M_LSRA_IMM(s1, 63, REG_ITMP2);
1070 M_LSRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
1071 M_LADD(s1, REG_ITMP2, REG_ITMP2);
1072 M_LSRA_IMM(REG_ITMP2, iptr->val.i, d);
1073 emit_store(jd, iptr, iptr->dst, d);
1076 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1078 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1079 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1080 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1082 emit_store(jd, iptr, iptr->dst, d);
1085 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
1086 /* val.i = constant */
1088 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1089 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1090 M_ISLL_IMM(s1, iptr->val.i, d);
1091 emit_store(jd, iptr, iptr->dst, d);
1094 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1096 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1097 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1098 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1100 emit_store(jd, iptr, iptr->dst, d);
1103 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
1104 /* val.i = constant */
1106 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1107 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1108 M_ISRA_IMM(s1, iptr->val.i, d);
1109 emit_store(jd, iptr, iptr->dst, d);
1112 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1114 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1115 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1116 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1118 emit_store(jd, iptr, iptr->dst, d);
1121 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1122 /* val.i = constant */
1124 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1125 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1126 M_ISRL_IMM(s1, iptr->val.i, d);
1127 emit_store(jd, iptr, iptr->dst, d);
1130 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1132 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1133 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1134 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1136 emit_store(jd, iptr, iptr->dst, d);
1139 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1140 /* val.i = constant */
1142 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1143 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1144 M_LSLL_IMM(s1, iptr->val.i, d);
1145 emit_store(jd, iptr, iptr->dst, d);
1148 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1150 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1151 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1152 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1154 emit_store(jd, iptr, iptr->dst, d);
1157 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1158 /* val.i = constant */
1160 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1161 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1162 M_LSRA_IMM(s1, iptr->val.i, d);
1163 emit_store(jd, iptr, iptr->dst, d);
1166 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1168 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1169 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1170 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1172 emit_store(jd, iptr, iptr->dst, d);
1175 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1176 /* val.i = constant */
1178 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1179 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1180 M_LSRL_IMM(s1, iptr->val.i, d);
1181 emit_store(jd, iptr, iptr->dst, d);
1184 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1187 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1188 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1189 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1191 emit_store(jd, iptr, iptr->dst, d);
1194 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1195 /* val.i = constant */
1197 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1198 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1199 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1200 M_AND_IMM(s1, iptr->val.i, d);
1202 ICONST(REG_ITMP2, iptr->val.i);
1203 M_AND(s1, REG_ITMP2, d);
1205 emit_store(jd, iptr, iptr->dst, d);
1208 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1209 /* val.i = constant */
1211 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1212 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1214 M_MOV(s1, REG_ITMP1);
1217 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1218 M_AND_IMM(s1, iptr->val.i, d);
1221 M_ISUB(REG_ZERO, s1, d);
1222 M_AND_IMM(d, iptr->val.i, d);
1224 ICONST(REG_ITMP2, iptr->val.i);
1225 M_AND(s1, REG_ITMP2, d);
1228 M_ISUB(REG_ZERO, s1, d);
1229 M_AND(d, REG_ITMP2, d);
1231 M_ISUB(REG_ZERO, d, d);
1232 emit_store(jd, iptr, iptr->dst, d);
1235 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1236 /* val.l = constant */
1238 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1239 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1240 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1241 M_AND_IMM(s1, iptr->val.l, d);
1243 LCONST(REG_ITMP2, iptr->val.l);
1244 M_AND(s1, REG_ITMP2, d);
1246 emit_store(jd, iptr, iptr->dst, d);
1249 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1250 /* val.l = constant */
1252 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1253 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1255 M_MOV(s1, REG_ITMP1);
1258 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1259 M_AND_IMM(s1, iptr->val.l, d);
1262 M_LSUB(REG_ZERO, s1, d);
1263 M_AND_IMM(d, iptr->val.l, d);
1265 LCONST(REG_ITMP2, iptr->val.l);
1266 M_AND(s1, REG_ITMP2, d);
1269 M_LSUB(REG_ZERO, s1, d);
1270 M_AND(d, REG_ITMP2, d);
1272 M_LSUB(REG_ZERO, d, d);
1273 emit_store(jd, iptr, iptr->dst, d);
1276 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1279 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1280 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1281 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1283 emit_store(jd, iptr, iptr->dst, d);
1286 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1287 /* val.i = constant */
1289 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1290 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1291 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1292 M_OR_IMM(s1, iptr->val.i, d);
1294 ICONST(REG_ITMP2, iptr->val.i);
1295 M_OR(s1, REG_ITMP2, d);
1297 emit_store(jd, iptr, iptr->dst, d);
1300 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1301 /* val.l = constant */
1303 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1304 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1305 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1306 M_OR_IMM(s1, iptr->val.l, d);
1308 LCONST(REG_ITMP2, iptr->val.l);
1309 M_OR(s1, REG_ITMP2, d);
1311 emit_store(jd, iptr, iptr->dst, d);
1314 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1317 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1318 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1319 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1321 emit_store(jd, iptr, iptr->dst, d);
1324 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1325 /* val.i = constant */
1327 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1328 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1329 if ((iptr->val.i >= 0) && (iptr->val.i <= 0xffff)) {
1330 M_XOR_IMM(s1, iptr->val.i, d);
1332 ICONST(REG_ITMP2, iptr->val.i);
1333 M_XOR(s1, REG_ITMP2, d);
1335 emit_store(jd, iptr, iptr->dst, d);
1338 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1339 /* val.l = constant */
1341 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1342 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1343 if ((iptr->val.l >= 0) && (iptr->val.l <= 0xffff)) {
1344 M_XOR_IMM(s1, iptr->val.l, d);
1346 LCONST(REG_ITMP2, iptr->val.l);
1347 M_XOR(s1, REG_ITMP2, d);
1349 emit_store(jd, iptr, iptr->dst, d);
1353 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1355 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1356 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1357 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1358 M_CMPLT(s1, s2, REG_ITMP3);
1359 M_CMPLT(s2, s1, REG_ITMP1);
1360 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1361 emit_store(jd, iptr, iptr->dst, d);
1365 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1366 /* op1 = variable, val.i = constant */
1368 var = &(rd->locals[iptr->op1][TYPE_INT]);
1369 if (var->flags & INMEMORY) {
1371 M_LLD(s1, REG_SP, var->regoff * 8);
1374 M_IADD_IMM(s1, iptr->val.i, s1);
1375 if (var->flags & INMEMORY)
1376 M_LST(s1, REG_SP, var->regoff * 8);
1380 /* floating operations ************************************************/
1382 case ICMD_FNEG: /* ..., value ==> ..., - value */
1384 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1385 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1387 emit_store(jd, iptr, iptr->dst, d);
1390 case ICMD_DNEG: /* ..., value ==> ..., - value */
1392 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1393 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1395 emit_store(jd, iptr, iptr->dst, d);
1398 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1400 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1401 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1402 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1404 emit_store(jd, iptr, iptr->dst, d);
1407 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1409 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1410 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1411 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1413 emit_store(jd, iptr, iptr->dst, d);
1416 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1418 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1419 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1420 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1422 emit_store(jd, iptr, iptr->dst, d);
1425 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1427 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1428 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1429 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1431 emit_store(jd, iptr, iptr->dst, d);
1434 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1436 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1437 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1438 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1440 emit_store(jd, iptr, iptr->dst, d);
1443 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1445 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1446 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1447 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1449 emit_store(jd, iptr, iptr->dst, d);
1452 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1454 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1455 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1456 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1458 emit_store(jd, iptr, iptr->dst, d);
1461 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1463 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1464 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1465 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1467 emit_store(jd, iptr, iptr->dst, d);
1471 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1473 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1474 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1475 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1476 M_FDIV(s1,s2, REG_FTMP3);
1477 M_FLOORFL(REG_FTMP3, REG_FTMP3);
1478 M_CVTLF(REG_FTMP3, REG_FTMP3);
1479 M_FMUL(REG_FTMP3, s2, REG_FTMP3);
1480 M_FSUB(s1, REG_FTMP3, d);
1481 emit_store(jd, iptr, iptr->dst, d);
1484 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
1486 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1487 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1488 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1489 M_DDIV(s1,s2, REG_FTMP3);
1490 M_FLOORDL(REG_FTMP3, REG_FTMP3);
1491 M_CVTLD(REG_FTMP3, REG_FTMP3);
1492 M_DMUL(REG_FTMP3, s2, REG_FTMP3);
1493 M_DSUB(s1, REG_FTMP3, d);
1494 emit_store(jd, iptr, iptr->dst, d);
1498 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1500 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1501 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1504 emit_store(jd, iptr, iptr->dst, d);
1507 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1509 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1510 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1513 emit_store(jd, iptr, iptr->dst, d);
1517 /* XXX these do not work correctly */
1519 case ICMD_F2I: /* ..., (float) value ==> ..., (int) value */
1521 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1522 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1523 M_TRUNCFI(s1, REG_FTMP1);
1524 M_MOVDI(REG_FTMP1, d);
1526 emit_store(jd, iptr, iptr->dst, d);
1529 case ICMD_D2I: /* ..., (double) value ==> ..., (int) value */
1531 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1532 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1533 M_TRUNCDI(s1, REG_FTMP1);
1534 M_MOVDI(REG_FTMP1, d);
1536 emit_store(jd, iptr, iptr->dst, d);
1539 case ICMD_F2L: /* ..., (float) value ==> ..., (long) value */
1541 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1542 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1543 M_TRUNCFL(s1, REG_FTMP1);
1544 M_MOVDL(REG_FTMP1, d);
1546 emit_store(jd, iptr, iptr->dst, d);
1549 case ICMD_D2L: /* ..., (double) value ==> ..., (long) value */
1551 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1552 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1553 M_TRUNCDL(s1, REG_FTMP1);
1554 M_MOVDL(REG_FTMP1, d);
1556 emit_store(jd, iptr, iptr->dst, d);
1560 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1562 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1563 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1565 emit_store(jd, iptr, iptr->dst, d);
1568 case ICMD_D2F: /* ..., value ==> ..., (double) value */
1570 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1571 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1573 emit_store(jd, iptr, iptr->dst, d);
1576 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1578 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1579 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1580 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1583 M_LADD_IMM(REG_ZERO, 1, d);
1587 M_LSUB_IMM(REG_ZERO, 1, d);
1588 M_CMOVT(REG_ZERO, d);
1589 emit_store(jd, iptr, iptr->dst, d);
1592 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1594 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1595 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1596 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1599 M_LADD_IMM(REG_ZERO, 1, d);
1603 M_LSUB_IMM(REG_ZERO, 1, d);
1604 M_CMOVT(REG_ZERO, d);
1605 emit_store(jd, iptr, iptr->dst, d);
1608 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1610 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1611 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1612 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1615 M_LSUB_IMM(REG_ZERO, 1, d);
1619 M_LADD_IMM(REG_ZERO, 1, d);
1620 M_CMOVT(REG_ZERO, d);
1621 emit_store(jd, iptr, iptr->dst, d);
1624 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1626 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1627 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1628 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
1631 M_LSUB_IMM(REG_ZERO, 1, d);
1635 M_LADD_IMM(REG_ZERO, 1, d);
1636 M_CMOVT(REG_ZERO, d);
1637 emit_store(jd, iptr, iptr->dst, d);
1641 /* memory operations **************************************************/
1643 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1645 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1646 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1647 gen_nullptr_check(s1);
1648 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1649 emit_store(jd, iptr, iptr->dst, d);
1652 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1654 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1655 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1656 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1657 if (iptr->op1 == 0) {
1658 gen_nullptr_check(s1);
1661 M_AADD(s2, s1, REG_ITMP3);
1662 M_BLDS(d, REG_ITMP3, OFFSET(java_bytearray, data[0]));
1663 emit_store(jd, iptr, iptr->dst, d);
1666 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1668 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1669 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1670 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1671 if (iptr->op1 == 0) {
1672 gen_nullptr_check(s1);
1675 M_AADD(s2, s1, REG_ITMP3);
1676 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1677 M_SLDU(d, REG_ITMP3, OFFSET(java_chararray, data[0]));
1678 emit_store(jd, iptr, iptr->dst, d);
1681 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1683 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1684 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1685 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1686 if (iptr->op1 == 0) {
1687 gen_nullptr_check(s1);
1690 M_AADD(s2, s1, REG_ITMP3);
1691 M_AADD(s2, REG_ITMP3, REG_ITMP3);
1692 M_SLDS(d, REG_ITMP3, OFFSET(java_shortarray, data[0]));
1693 emit_store(jd, iptr, iptr->dst, d);
1696 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1698 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1699 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1700 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1701 if (iptr->op1 == 0) {
1702 gen_nullptr_check(s1);
1705 M_ASLL_IMM(s2, 2, REG_ITMP3);
1706 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1707 M_ILD(d, REG_ITMP3, OFFSET(java_intarray, data[0]));
1708 emit_store(jd, iptr, iptr->dst, d);
1711 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1713 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1714 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1715 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1716 if (iptr->op1 == 0) {
1717 gen_nullptr_check(s1);
1720 M_ASLL_IMM(s2, 3, REG_ITMP3);
1721 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1722 M_LLD(d, REG_ITMP3, OFFSET(java_longarray, data[0]));
1723 emit_store(jd, iptr, iptr->dst, d);
1726 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1728 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1729 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1730 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1731 if (iptr->op1 == 0) {
1732 gen_nullptr_check(s1);
1735 M_ASLL_IMM(s2, 2, REG_ITMP3);
1736 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1737 M_FLD(d, REG_ITMP3, OFFSET(java_floatarray, data[0]));
1738 emit_store(jd, iptr, iptr->dst, d);
1741 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1743 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1744 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1745 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1746 if (iptr->op1 == 0) {
1747 gen_nullptr_check(s1);
1750 M_ASLL_IMM(s2, 3, REG_ITMP3);
1751 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1752 M_DLD(d, REG_ITMP3, OFFSET(java_doublearray, data[0]));
1753 emit_store(jd, iptr, iptr->dst, d);
1756 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1758 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1759 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1760 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1761 if (iptr->op1 == 0) {
1762 gen_nullptr_check(s1);
1765 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP3);
1766 M_AADD(REG_ITMP3, s1, REG_ITMP3);
1767 M_ALD(d, REG_ITMP3, OFFSET(java_objectarray, data[0]));
1768 emit_store(jd, iptr, iptr->dst, d);
1772 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1774 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1775 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1776 if (iptr->op1 == 0) {
1777 gen_nullptr_check(s1);
1780 M_AADD(s2, s1, REG_ITMP1);
1781 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1782 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1785 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1786 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1788 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1789 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1790 if (iptr->op1 == 0) {
1791 gen_nullptr_check(s1);
1794 M_AADD(s2, s1, REG_ITMP1);
1795 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1796 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1797 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1800 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1802 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1803 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1804 if (iptr->op1 == 0) {
1805 gen_nullptr_check(s1);
1808 M_ASLL_IMM(s2, 2, REG_ITMP2);
1809 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1810 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1811 M_IST_INTERN(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1814 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1816 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1817 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1818 if (iptr->op1 == 0) {
1819 gen_nullptr_check(s1);
1822 M_ASLL_IMM(s2, 3, REG_ITMP2);
1823 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1824 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1825 M_LST_INTERN(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1828 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1830 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1831 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1832 if (iptr->op1 == 0) {
1833 gen_nullptr_check(s1);
1836 M_ASLL_IMM(s2, 2, REG_ITMP2);
1837 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1838 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1839 M_FST_INTERN(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1842 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1844 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1845 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1846 if (iptr->op1 == 0) {
1847 gen_nullptr_check(s1);
1850 M_ASLL_IMM(s2, 3, REG_ITMP2);
1851 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1852 s3 = emit_load_s3(jd, iptr, src, REG_FTMP1);
1853 M_DST_INTERN(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1857 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1859 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1860 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1861 if (iptr->op1 == 0) {
1862 gen_nullptr_check(s1);
1865 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1867 M_MOV(s1, rd->argintregs[0]);
1868 M_MOV(s3, rd->argintregs[1]);
1869 disp = dseg_addaddress(cd, BUILTIN_canstore);
1870 M_ALD(REG_ITMP3, REG_PV, disp);
1871 M_JSR(REG_RA, REG_ITMP3);
1874 M_BEQZ(REG_RESULT, 0);
1875 codegen_add_arraystoreexception_ref(cd);
1878 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1879 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1880 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1881 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1882 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1883 M_AST_INTERN(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1887 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1889 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1890 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1891 if (iptr->op1 == 0) {
1892 gen_nullptr_check(s1);
1895 M_AADD(s2, s1, REG_ITMP1);
1896 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1899 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1900 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1902 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1903 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1904 if (iptr->op1 == 0) {
1905 gen_nullptr_check(s1);
1908 M_AADD(s2, s1, REG_ITMP1);
1909 M_AADD(s2, REG_ITMP1, REG_ITMP1);
1910 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1913 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1915 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1916 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1917 if (iptr->op1 == 0) {
1918 gen_nullptr_check(s1);
1921 M_ASLL_IMM(s2, 2, REG_ITMP2);
1922 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1923 M_IST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1926 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1928 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1929 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1930 if (iptr->op1 == 0) {
1931 gen_nullptr_check(s1);
1934 M_ASLL_IMM(s2, 3, REG_ITMP2);
1935 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1936 M_LST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1939 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1941 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1942 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1943 if (iptr->op1 == 0) {
1944 gen_nullptr_check(s1);
1947 M_ASLL_IMM(s2, POINTERSHIFT, REG_ITMP2);
1948 M_AADD(REG_ITMP2, s1, REG_ITMP1);
1949 M_AST_INTERN(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1953 case ICMD_GETSTATIC: /* ... ==> ..., value */
1954 /* op1 = type, val.a = field address */
1956 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1957 disp = dseg_addaddress(cd, NULL);
1959 codegen_addpatchref(cd, PATCHER_get_putstatic,
1960 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
1962 if (opt_showdisassemble) {
1967 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
1969 disp = dseg_addaddress(cd, &(fi->value));
1971 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
1972 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
1974 if (opt_showdisassemble) {
1980 M_ALD(REG_ITMP1, REG_PV, disp);
1981 switch (iptr->op1) {
1983 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1984 M_ILD_INTERN(d, REG_ITMP1, 0);
1985 emit_store(jd, iptr, iptr->dst, d);
1988 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1989 M_LLD_INTERN(d, REG_ITMP1, 0);
1990 emit_store(jd, iptr, iptr->dst, d);
1993 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1994 M_ALD_INTERN(d, REG_ITMP1, 0);
1995 emit_store(jd, iptr, iptr->dst, d);
1998 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
1999 M_FLD_INTERN(d, REG_ITMP1, 0);
2000 emit_store(jd, iptr, iptr->dst, d);
2003 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2004 M_DLD_INTERN(d, REG_ITMP1, 0);
2005 emit_store(jd, iptr, iptr->dst, d);
2010 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2011 /* op1 = type, val.a = field address */
2013 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2014 disp = dseg_addaddress(cd, NULL);
2016 codegen_addpatchref(cd, PATCHER_get_putstatic,
2017 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2019 if (opt_showdisassemble) {
2024 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2026 disp = dseg_addaddress(cd, &(fi->value));
2028 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2029 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2031 if (opt_showdisassemble) {
2037 M_ALD(REG_ITMP1, REG_PV, disp);
2038 switch (iptr->op1) {
2040 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2041 M_IST_INTERN(s2, REG_ITMP1, 0);
2044 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2045 M_LST_INTERN(s2, REG_ITMP1, 0);
2048 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2049 M_AST_INTERN(s2, REG_ITMP1, 0);
2052 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2053 M_FST_INTERN(s2, REG_ITMP1, 0);
2056 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2057 M_DST_INTERN(s2, REG_ITMP1, 0);
2062 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2063 /* val = value (in current instruction) */
2064 /* op1 = type, val.a = field address (in */
2065 /* following NOP) */
2067 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2068 disp = dseg_addaddress(cd, NULL);
2070 codegen_addpatchref(cd, PATCHER_get_putstatic,
2071 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2073 if (opt_showdisassemble) {
2078 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2080 disp = dseg_addaddress(cd, &(fi->value));
2082 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2083 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2085 if (opt_showdisassemble) {
2091 M_ALD(REG_ITMP1, REG_PV, disp);
2092 switch (iptr->op1) {
2094 M_IST_INTERN(REG_ZERO, REG_ITMP1, 0);
2097 M_LST_INTERN(REG_ZERO, REG_ITMP1, 0);
2100 M_AST_INTERN(REG_ZERO, REG_ITMP1, 0);
2103 M_FST_INTERN(REG_ZERO, REG_ITMP1, 0);
2106 M_DST_INTERN(REG_ZERO, REG_ITMP1, 0);
2112 case ICMD_GETFIELD: /* ... ==> ..., value */
2113 /* op1 = type, val.i = field offset */
2115 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2116 gen_nullptr_check(s1);
2118 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2119 codegen_addpatchref(cd, PATCHER_get_putfield,
2120 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2122 if (opt_showdisassemble) {
2129 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2132 switch (iptr->op1) {
2134 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2136 emit_store(jd, iptr, iptr->dst, d);
2139 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2141 emit_store(jd, iptr, iptr->dst, d);
2144 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2146 emit_store(jd, iptr, iptr->dst, d);
2149 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2151 emit_store(jd, iptr, iptr->dst, d);
2154 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2156 emit_store(jd, iptr, iptr->dst, d);
2161 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2162 /* op1 = type, val.a = field address */
2164 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2165 gen_nullptr_check(s1);
2167 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2168 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2170 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2173 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2174 codegen_addpatchref(cd, PATCHER_get_putfield,
2175 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2177 if (opt_showdisassemble) {
2184 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2187 switch (iptr->op1) {
2206 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2207 /* val = value (in current instruction) */
2208 /* op1 = type, val.a = field address (in */
2209 /* following NOP) */
2211 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2212 gen_nullptr_check(s1);
2214 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2215 codegen_addpatchref(cd, PATCHER_get_putfield,
2216 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2218 if (opt_showdisassemble) {
2225 a = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2228 switch (iptr[1].op1) {
2230 M_IST(REG_ZERO, s1, a);
2233 M_LST(REG_ZERO, s1, a);
2236 M_AST(REG_ZERO, s1, a);
2239 M_FST(REG_ZERO, s1, a);
2242 M_DST(REG_ZERO, s1, a);
2248 /* branch operations **************************************************/
2250 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2252 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2253 M_INTMOVE(s1, REG_ITMP1_XPTR);
2255 #ifdef ENABLE_VERIFIER
2257 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2258 (unresolved_class *) iptr->val.a, 0);
2260 if (opt_showdisassemble) {
2264 #endif /* ENABLE_VERIFIER */
2266 disp = dseg_addaddress(cd, asm_handle_exception);
2267 M_ALD(REG_ITMP2, REG_PV, disp);
2268 M_JSR(REG_ITMP2_XPC, REG_ITMP2);
2270 M_NOP; /* nop ensures that XPC is less than the end */
2271 /* of basic block */
2275 case ICMD_GOTO: /* ... ==> ... */
2276 /* op1 = target JavaVM pc */
2278 codegen_addreference(cd, (basicblock *) iptr->target);
2283 case ICMD_JSR: /* ... ==> ... */
2284 /* op1 = target JavaVM pc */
2286 dseg_addtarget(cd, (basicblock *) iptr->target);
2287 M_ALD(REG_ITMP1, REG_PV, -(cd->dseglen));
2288 M_JSR(REG_ITMP1, REG_ITMP1); /* REG_ITMP1 = return address */
2292 case ICMD_RET: /* ... ==> ... */
2293 /* op1 = local variable */
2294 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2295 if (var->flags & INMEMORY) {
2296 M_ALD(REG_ITMP1, REG_SP, var->regoff * 8);
2304 case ICMD_IFNULL: /* ..., value ==> ... */
2305 /* op1 = target JavaVM pc */
2307 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2309 codegen_addreference(cd, (basicblock *) iptr->target);
2313 case ICMD_IFNONNULL: /* ..., value ==> ... */
2314 /* op1 = target JavaVM pc */
2316 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2318 codegen_addreference(cd, (basicblock *) iptr->target);
2322 case ICMD_IFEQ: /* ..., value ==> ... */
2323 /* op1 = target JavaVM pc, val.i = constant */
2325 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2326 if (iptr->val.i == 0) {
2329 ICONST(REG_ITMP2, iptr->val.i);
2330 M_BEQ(s1, REG_ITMP2, 0);
2332 codegen_addreference(cd, (basicblock *) iptr->target);
2336 case ICMD_IFLT: /* ..., value ==> ... */
2337 /* op1 = target JavaVM pc, val.i = constant */
2339 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2340 if (iptr->val.i == 0) {
2343 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2344 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2346 ICONST(REG_ITMP2, iptr->val.i);
2347 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2349 M_BNEZ(REG_ITMP1, 0);
2351 codegen_addreference(cd, (basicblock *) iptr->target);
2355 case ICMD_IFLE: /* ..., value ==> ... */
2356 /* op1 = target JavaVM pc, val.i = constant */
2358 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2359 if (iptr->val.i == 0) {
2363 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2364 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2365 M_BNEZ(REG_ITMP1, 0);
2368 ICONST(REG_ITMP2, iptr->val.i);
2369 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2370 M_BEQZ(REG_ITMP1, 0);
2373 codegen_addreference(cd, (basicblock *) iptr->target);
2377 case ICMD_IFNE: /* ..., value ==> ... */
2378 /* op1 = target JavaVM pc, val.i = constant */
2380 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2381 if (iptr->val.i == 0) {
2385 ICONST(REG_ITMP2, iptr->val.i);
2386 M_BNE(s1, REG_ITMP2, 0);
2388 codegen_addreference(cd, (basicblock *) iptr->target);
2392 case ICMD_IFGT: /* ..., value ==> ... */
2393 /* op1 = target JavaVM pc, val.i = constant */
2395 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2396 if (iptr->val.i == 0) {
2400 if ((iptr->val.i >= -32769) && (iptr->val.i <= 32766)) {
2401 M_CMPLT_IMM(s1, iptr->val.i + 1, REG_ITMP1);
2402 M_BEQZ(REG_ITMP1, 0);
2405 ICONST(REG_ITMP2, iptr->val.i);
2406 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2407 M_BNEZ(REG_ITMP1, 0);
2410 codegen_addreference(cd, (basicblock *) iptr->target);
2414 case ICMD_IFGE: /* ..., value ==> ... */
2415 /* op1 = target JavaVM pc, val.i = constant */
2417 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2418 if (iptr->val.i == 0) {
2422 if ((iptr->val.i >= -32768) && (iptr->val.i <= 32767)) {
2423 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2426 ICONST(REG_ITMP2, iptr->val.i);
2427 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2429 M_BEQZ(REG_ITMP1, 0);
2431 codegen_addreference(cd, (basicblock *) iptr->target);
2435 case ICMD_IF_LEQ: /* ..., value ==> ... */
2436 /* op1 = target JavaVM pc, val.l = constant */
2438 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2439 if (iptr->val.l == 0) {
2443 LCONST(REG_ITMP2, iptr->val.l);
2444 M_BEQ(s1, REG_ITMP2, 0);
2446 codegen_addreference(cd, (basicblock *) iptr->target);
2450 case ICMD_IF_LLT: /* ..., value ==> ... */
2451 /* op1 = target JavaVM pc, val.l = constant */
2453 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2454 if (iptr->val.l == 0) {
2458 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2459 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2462 LCONST(REG_ITMP2, iptr->val.l);
2463 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2465 M_BNEZ(REG_ITMP1, 0);
2467 codegen_addreference(cd, (basicblock *) iptr->target);
2471 case ICMD_IF_LLE: /* ..., value ==> ... */
2472 /* op1 = target JavaVM pc, val.l = constant */
2474 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2475 if (iptr->val.l == 0) {
2479 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2480 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2481 M_BNEZ(REG_ITMP1, 0);
2484 LCONST(REG_ITMP2, iptr->val.l);
2485 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2486 M_BEQZ(REG_ITMP1, 0);
2489 codegen_addreference(cd, (basicblock *) iptr->target);
2493 case ICMD_IF_LNE: /* ..., value ==> ... */
2494 /* op1 = target JavaVM pc, val.l = constant */
2496 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2497 if (iptr->val.l == 0) {
2501 LCONST(REG_ITMP2, iptr->val.l);
2502 M_BNE(s1, REG_ITMP2, 0);
2504 codegen_addreference(cd, (basicblock *) iptr->target);
2508 case ICMD_IF_LGT: /* ..., value ==> ... */
2509 /* op1 = target JavaVM pc, val.l = constant */
2511 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2512 if (iptr->val.l == 0) {
2516 if ((iptr->val.l >= -32769) && (iptr->val.l <= 32766)) {
2517 M_CMPLT_IMM(s1, iptr->val.l + 1, REG_ITMP1);
2518 M_BEQZ(REG_ITMP1, 0);
2521 LCONST(REG_ITMP2, iptr->val.l);
2522 M_CMPGT(s1, REG_ITMP2, REG_ITMP1);
2523 M_BNEZ(REG_ITMP1, 0);
2526 codegen_addreference(cd, (basicblock *) iptr->target);
2530 case ICMD_IF_LGE: /* ..., value ==> ... */
2531 /* op1 = target JavaVM pc, val.l = constant */
2533 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2534 if (iptr->val.l == 0) {
2538 if ((iptr->val.l >= -32768) && (iptr->val.l <= 32767)) {
2539 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2542 LCONST(REG_ITMP2, iptr->val.l);
2543 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2545 M_BEQZ(REG_ITMP1, 0);
2547 codegen_addreference(cd, (basicblock *) iptr->target);
2551 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2552 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2553 case ICMD_IF_ACMPEQ:
2555 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2556 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2558 codegen_addreference(cd, (basicblock *) iptr->target);
2562 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2563 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2564 case ICMD_IF_ACMPNE:
2566 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2567 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2569 codegen_addreference(cd, (basicblock *) iptr->target);
2573 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2574 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2576 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2577 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2578 M_CMPLT(s1, s2, REG_ITMP1);
2579 M_BNEZ(REG_ITMP1, 0);
2580 codegen_addreference(cd, (basicblock *) iptr->target);
2584 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2585 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2587 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2588 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2589 M_CMPGT(s1, s2, REG_ITMP1);
2590 M_BNEZ(REG_ITMP1, 0);
2591 codegen_addreference(cd, (basicblock *) iptr->target);
2595 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2596 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2598 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2599 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2600 M_CMPGT(s1, s2, REG_ITMP1);
2601 M_BEQZ(REG_ITMP1, 0);
2602 codegen_addreference(cd, (basicblock *) iptr->target);
2606 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2607 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2609 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2610 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2611 M_CMPLT(s1, s2, REG_ITMP1);
2612 M_BEQZ(REG_ITMP1, 0);
2613 codegen_addreference(cd, (basicblock *) iptr->target);
2617 #ifdef CONDITIONAL_LOADCONST
2618 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2620 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2623 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2624 /* val.i = constant */
2626 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2627 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2629 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2630 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2631 M_CMPEQ(s1, REG_ZERO, d);
2632 emit_store(jd, iptr, iptr->dst, d);
2635 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2636 M_CMPEQ(s1, REG_ZERO, d);
2638 emit_store(jd, iptr, iptr->dst, d);
2642 M_MOV(s1, REG_ITMP1);
2645 ICONST(d, iptr[1].val.i);
2647 if ((s3 >= 0) && (s3 <= 255)) {
2648 M_CMOVEQ_IMM(s1, s3, d);
2650 ICONST(REG_ITMP3, s3);
2651 M_CMOVEQ(s1, REG_ITMP3, d);
2653 emit_store(jd, iptr, iptr->dst, d);
2656 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2657 /* val.i = constant */
2659 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2660 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2662 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2663 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2664 M_CMPEQ(s1, REG_ZERO, d);
2665 emit_store(jd, iptr, iptr->dst, d);
2668 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2669 M_CMPEQ(s1, REG_ZERO, d);
2671 emit_store(jd, iptr, iptr->dst, d);
2675 M_MOV(s1, REG_ITMP1);
2678 ICONST(d, iptr[1].val.i);
2680 if ((s3 >= 0) && (s3 <= 255)) {
2681 M_CMOVNE_IMM(s1, s3, d);
2683 ICONST(REG_ITMP3, s3);
2684 M_CMOVNE(s1, REG_ITMP3, d);
2686 emit_store(jd, iptr, iptr->dst, d);
2689 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2690 /* val.i = constant */
2692 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2693 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2695 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2696 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2697 M_CMPLT(s1, REG_ZERO, d);
2698 emit_store(jd, iptr, iptr->dst, d);
2701 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2702 M_CMPLE(REG_ZERO, s1, d);
2703 emit_store(jd, iptr, iptr->dst, d);
2707 M_MOV(s1, REG_ITMP1);
2710 ICONST(d, iptr[1].val.i);
2712 if ((s3 >= 0) && (s3 <= 255)) {
2713 M_CMOVLT_IMM(s1, s3, d);
2715 ICONST(REG_ITMP3, s3);
2716 M_CMOVLT(s1, REG_ITMP3, d);
2718 emit_store(jd, iptr, iptr->dst, d);
2721 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2722 /* val.i = constant */
2724 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2725 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2727 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2728 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2729 M_CMPLE(REG_ZERO, s1, d);
2730 emit_store(jd, iptr, iptr->dst, d);
2733 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2734 M_CMPLT(s1, REG_ZERO, d);
2735 emit_store(jd, iptr, iptr->dst, d);
2739 M_MOV(s1, REG_ITMP1);
2742 ICONST(d, iptr[1].val.i);
2744 if ((s3 >= 0) && (s3 <= 255)) {
2745 M_CMOVGE_IMM(s1, s3, d);
2747 ICONST(REG_ITMP3, s3);
2748 M_CMOVGE(s1, REG_ITMP3, d);
2750 emit_store(jd, iptr, iptr->dst, d);
2753 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2754 /* val.i = constant */
2756 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2757 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2759 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2760 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2761 M_CMPLT(REG_ZERO, s1, d);
2762 emit_store(jd, iptr, iptr->dst, d);
2765 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2766 M_CMPLE(s1, REG_ZERO, d);
2767 emit_store(jd, iptr, iptr->dst, d);
2771 M_MOV(s1, REG_ITMP1);
2774 ICONST(d, iptr[1].val.i);
2776 if ((s3 >= 0) && (s3 <= 255)) {
2777 M_CMOVGT_IMM(s1, s3, d);
2779 ICONST(REG_ITMP3, s3);
2780 M_CMOVGT(s1, REG_ITMP3, d);
2782 emit_store(jd, iptr, iptr->dst, d);
2785 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2786 /* val.i = constant */
2788 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2789 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2791 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2792 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2793 M_CMPLE(s1, REG_ZERO, d);
2794 emit_store(jd, iptr, iptr->dst, d);
2797 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2798 M_CMPLT(REG_ZERO, s1, d);
2799 emit_store(jd, iptr, iptr->dst, d);
2803 M_MOV(s1, REG_ITMP1);
2806 ICONST(d, iptr[1].val.i);
2808 if ((s3 >= 0) && (s3 <= 255)) {
2809 M_CMOVLE_IMM(s1, s3, d);
2811 ICONST(REG_ITMP3, s3);
2812 M_CMOVLE(s1, REG_ITMP3, d);
2814 emit_store(jd, iptr, iptr->dst, d);
2819 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2822 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2823 M_INTMOVE(s1, REG_RESULT);
2824 goto nowperformreturn;
2826 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2828 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2829 M_INTMOVE(s1, REG_RESULT);
2831 #ifdef ENABLE_VERIFIER
2833 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2834 (unresolved_class *) iptr->val.a, 0);
2836 if (opt_showdisassemble) {
2840 #endif /* ENABLE_VERIFIER */
2841 goto nowperformreturn;
2843 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2845 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2846 M_FLTMOVE(s1, REG_FRESULT);
2847 goto nowperformreturn;
2849 case ICMD_DRETURN: /* ..., retvalue ==> ... */
2851 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2852 M_DBLMOVE(s1, REG_FRESULT);
2853 goto nowperformreturn;
2855 case ICMD_RETURN: /* ... ==> ... */
2861 p = parentargs_base;
2863 /* call trace function */
2865 if (opt_verbosecall) {
2866 M_LDA(REG_SP, REG_SP, -3 * 8);
2867 M_LST(REG_RA, REG_SP, 0 * 8);
2868 M_LST(REG_RESULT, REG_SP, 1 * 8);
2869 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2871 disp = dseg_addaddress(cd, m);
2872 M_ALD(rd->argintregs[0], REG_PV, disp);
2873 M_MOV(REG_RESULT, rd->argintregs[1]);
2874 M_DMOV(REG_FRESULT, rd->argfltregs[2]);
2875 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
2877 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2878 M_ALD(REG_ITMP3, REG_PV, disp);
2879 M_JSR(REG_RA, REG_ITMP3);
2882 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2883 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2884 M_LLD(REG_RA, REG_SP, 0 * 8);
2885 M_LDA(REG_SP, REG_SP, 3 * 8);
2888 #if defined(ENABLE_THREADS)
2889 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2890 disp = dseg_addaddress(cd, (void *) builtin_monitorexit);
2891 M_ALD(REG_ITMP3, REG_PV, disp);
2893 /* we need to save the proper return value */
2895 switch (iptr->opc) {
2899 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2900 M_JSR(REG_RA, REG_ITMP3);
2901 M_LST(REG_RESULT, REG_SP, rd->memuse * 8); /* delay slot */
2905 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2906 M_JSR(REG_RA, REG_ITMP3);
2907 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8); /* delay slot */
2910 M_JSR(REG_RA, REG_ITMP3);
2911 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8); /* delay*/
2915 /* and now restore the proper return value */
2917 switch (iptr->opc) {
2921 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2925 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2931 /* restore return address */
2933 if (!m->isleafmethod) {
2934 p--; M_ALD(REG_RA, REG_SP, p * 8);
2937 /* restore saved registers */
2939 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2940 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2942 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2943 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2946 /* deallocate stack and return */
2948 if (parentargs_base) {
2951 disp = parentargs_base * 8;
2952 lo = (short) (disp);
2953 hi = (short) (((disp) - lo) >> 16);
2957 M_LADD_IMM(REG_SP, lo, REG_SP); /* delay slot */
2959 M_LUI(REG_ITMP3,hi);
2960 M_LADD_IMM(REG_ITMP3,lo,REG_ITMP3);
2962 M_LADD(REG_ITMP3,REG_SP,REG_SP); /* delay slot */
2975 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2980 tptr = (void **) iptr->target;
2982 s4ptr = iptr->val.a;
2983 l = s4ptr[1]; /* low */
2984 i = s4ptr[2]; /* high */
2986 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2988 {M_INTMOVE(s1, REG_ITMP1);}
2989 else if (l <= 32768) {
2990 M_IADD_IMM(s1, -l, REG_ITMP1);
2993 ICONST(REG_ITMP2, l);
2994 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3000 M_CMPULT_IMM(REG_ITMP1, i, REG_ITMP2);
3001 M_BEQZ(REG_ITMP2, 0);
3002 codegen_addreference(cd, (basicblock *) tptr[0]);
3003 M_ASLL_IMM(REG_ITMP1, POINTERSHIFT, REG_ITMP1); /* delay slot*/
3005 /* build jump table top down and use address of lowest entry */
3007 /* s4ptr += 3 + i; */
3011 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3012 dseg_addtarget(cd, (basicblock *) tptr[0]);
3017 /* length of dataseg after last dseg_addtarget is used by load */
3019 M_AADD(REG_ITMP1, REG_PV, REG_ITMP2);
3020 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3027 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3029 s4 i, /*l, */val, *s4ptr;
3032 tptr = (void **) iptr->target;
3034 s4ptr = iptr->val.a;
3035 /*l = s4ptr[0];*/ /* default */
3036 i = s4ptr[1]; /* count */
3038 MCODECHECK((i<<2)+8);
3039 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3045 ICONST(REG_ITMP2, val);
3046 M_BEQ(s1, REG_ITMP2, 0);
3047 codegen_addreference(cd, (basicblock *) tptr[0]);
3052 tptr = (void **) iptr->target;
3053 codegen_addreference(cd, (basicblock *) tptr[0]);
3060 case ICMD_BUILTIN: /* ..., arg1 ==> ... */
3061 /* op1 = arg count val.a = builtintable entry */
3067 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3068 /* op1 = arg count, val.a = method pointer */
3070 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3071 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3072 case ICMD_INVOKEINTERFACE:
3074 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3075 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3079 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3080 md = lm->parseddesc;
3084 s3 = md->paramcount;
3086 MCODECHECK((s3 << 1) + 64);
3088 /* copy arguments to registers or stack location */
3090 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3091 if (src->varkind == ARGVAR)
3093 if (IS_INT_LNG_TYPE(src->type)) {
3094 if (!md->params[s3].inmemory) {
3095 s1 = rd->argintregs[md->params[s3].regoff];
3096 d = emit_load_s1(jd, iptr, src, s1);
3099 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3100 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3104 if (!md->params[s3].inmemory) {
3105 s1 = rd->argfltregs[md->params[s3].regoff];
3106 d = emit_load_s1(jd, iptr, src, s1);
3107 if (IS_2_WORD_TYPE(src->type))
3113 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3114 if (IS_2_WORD_TYPE(src->type))
3115 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3117 M_FST(d, REG_SP, md->params[s3].regoff * 8);
3122 switch (iptr->opc) {
3124 disp = dseg_addaddress(cd, bte->fp);
3125 d = md->returntype.type;
3127 M_ALD(REG_ITMP3, REG_PV, disp); /* built-in-function pointer */
3128 M_JSR(REG_RA, REG_ITMP3);
3130 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3131 M_LDA(REG_PV, REG_RA, -disp);
3133 /* if op1 == true, we need to check for an exception */
3135 if (iptr->op1 == true) {
3136 M_BEQZ(REG_RESULT, 0);
3137 codegen_add_fillinstacktrace_ref(cd);
3142 case ICMD_INVOKESPECIAL:
3143 M_BEQZ(rd->argintregs[0], 0);
3144 codegen_add_nullpointerexception_ref(cd);
3148 case ICMD_INVOKESTATIC:
3150 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3152 disp = dseg_addaddress(cd, NULL);
3154 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3157 if (opt_showdisassemble) {
3161 d = um->methodref->parseddesc.md->returntype.type;
3164 disp = dseg_addaddress(cd, lm->stubroutine);
3165 d = lm->parseddesc->returntype.type;
3168 M_ALD(REG_PV, REG_PV, disp); /* method pointer in pv */
3169 M_JSR(REG_RA, REG_PV);
3171 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3172 M_LDA(REG_PV, REG_RA, -disp);
3175 case ICMD_INVOKEVIRTUAL:
3176 gen_nullptr_check(rd->argintregs[0]);
3179 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3181 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3183 if (opt_showdisassemble) {
3188 d = um->methodref->parseddesc.md->returntype.type;
3191 s1 = OFFSET(vftbl_t, table[0]) +
3192 sizeof(methodptr) * lm->vftblindex;
3193 d = lm->parseddesc->returntype.type;
3196 M_ALD(REG_METHODPTR, rd->argintregs[0],
3197 OFFSET(java_objectheader, vftbl));
3198 M_ALD(REG_PV, REG_METHODPTR, s1);
3199 M_JSR(REG_RA, REG_PV);
3201 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3202 M_LDA(REG_PV, REG_RA, -disp);
3205 case ICMD_INVOKEINTERFACE:
3206 gen_nullptr_check(rd->argintregs[0]);
3209 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3211 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3213 if (opt_showdisassemble) {
3219 d = um->methodref->parseddesc.md->returntype.type;
3222 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3223 sizeof(methodptr*) * lm->class->index;
3225 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3227 d = lm->parseddesc->returntype.type;
3230 M_ALD(REG_METHODPTR, rd->argintregs[0],
3231 OFFSET(java_objectheader, vftbl));
3232 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3233 M_ALD(REG_PV, REG_METHODPTR, s2);
3234 M_JSR(REG_RA, REG_PV);
3236 disp = (s4) (cd->mcodeptr - cd->mcodebase);
3237 M_LDA(REG_PV, REG_RA, -disp);
3241 /* d contains return type */
3243 if (d != TYPE_VOID) {
3244 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3245 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3246 M_INTMOVE(REG_RESULT, s1);
3248 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3249 if (IS_2_WORD_TYPE(iptr->dst->type))
3250 M_DMOV(REG_FRESULT, s1);
3252 M_FMOV(REG_FRESULT, s1);
3254 emit_store(jd, iptr, iptr->dst, s1);
3259 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3260 /* op1: 0 == array, 1 == class */
3261 /* val.a: (classinfo*) superclass */
3263 /* superclass is an interface:
3265 * OK if ((sub == NULL) ||
3266 * (sub->vftbl->interfacetablelength > super->index) &&
3267 * (sub->vftbl->interfacetable[-super->index] != NULL));
3269 * superclass is a class:
3271 * OK if ((sub == NULL) || (0
3272 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3273 * super->vftbl->diffvall));
3276 if (iptr->op1 == 1) {
3278 vftbl_t *supervftbl;
3281 super = (classinfo *) iptr->val.a;
3288 superindex = super->index;
3289 supervftbl = super->vftbl;
3292 #if defined(ENABLE_THREADS)
3293 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3296 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3298 /* calculate interface checkcast code size */
3302 s2 += (opt_showdisassemble ? 2 : 0);
3304 /* calculate class checkcast code size */
3306 s3 = 10 /* 10 + (s1 == REG_ITMP1) */;
3308 s3 += (opt_showdisassemble ? 2 : 0);
3310 /* if class is not resolved, check which code to call */
3313 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3316 disp = dseg_adds4(cd, 0); /* super->flags */
3318 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3319 (constant_classref *) iptr->target,
3322 if (opt_showdisassemble) {
3326 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3327 M_ILD(REG_ITMP2, REG_PV, disp);
3328 M_AND_IMM(REG_ITMP2, ACC_INTERFACE, REG_ITMP2);
3329 M_BEQZ(REG_ITMP2, 1 + s2 + 2);
3333 /* interface checkcast code */
3335 if (!super || super->flags & ACC_INTERFACE) {
3341 codegen_addpatchref(cd,
3342 PATCHER_checkcast_instanceof_interface,
3343 (constant_classref *) iptr->target,
3346 if (opt_showdisassemble) {
3351 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3352 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3353 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3354 M_BLEZ(REG_ITMP3, 0);
3355 codegen_add_classcastexception_ref(cd);
3357 M_ALD(REG_ITMP3, REG_ITMP2,
3358 OFFSET(vftbl_t, interfacetable[0]) -
3359 superindex * sizeof(methodptr*));
3360 M_BEQZ(REG_ITMP3, 0);
3361 codegen_add_classcastexception_ref(cd);
3370 /* class checkcast code */
3372 if (!super || !(super->flags & ACC_INTERFACE)) {
3373 disp = dseg_addaddress(cd, (void *) supervftbl);
3380 codegen_addpatchref(cd,
3381 PATCHER_checkcast_instanceof_class,
3382 (constant_classref *) iptr->target,
3385 if (opt_showdisassemble) {
3390 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3391 M_ALD(REG_ITMP3, REG_PV, disp);
3392 #if defined(ENABLE_THREADS)
3393 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3395 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3396 /* if (s1 != REG_ITMP1) { */
3397 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3398 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3399 /* #if defined(ENABLE_THREADS) */
3400 /* codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase); */
3402 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3404 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3405 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3406 M_ALD(REG_ITMP3, REG_PV, disp);
3407 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3408 #if defined(ENABLE_THREADS)
3409 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3412 M_CMPULT(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3413 M_BNEZ(REG_ITMP3, 0);
3414 codegen_add_classcastexception_ref(cd);
3417 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3420 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3421 M_INTMOVE(s1, rd->argintregs[0]);
3423 disp = dseg_addaddress(cd, iptr->val.a);
3425 if (iptr->val.a == NULL) {
3426 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3427 (constant_classref *) iptr->target,
3430 if (opt_showdisassemble) {
3435 M_ALD(rd->argintregs[1], REG_PV, disp);
3436 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3437 M_ALD(REG_ITMP3, REG_PV, disp);
3438 M_JSR(REG_RA, REG_ITMP3);
3441 M_BEQZ(REG_RESULT, 0);
3442 codegen_add_classcastexception_ref(cd);
3445 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3446 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3449 emit_store(jd, iptr, iptr->dst, d);
3452 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3453 /* op1: 0 == array, 1 == class */
3454 /* val.a: (classinfo*) superclass */
3456 /* superclass is an interface:
3458 * return (sub != NULL) &&
3459 * (sub->vftbl->interfacetablelength > super->index) &&
3460 * (sub->vftbl->interfacetable[-super->index] != NULL);
3462 * superclass is a class:
3464 * return ((sub != NULL) && (0
3465 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3466 * super->vftbl->diffvall));
3471 vftbl_t *supervftbl;
3474 super = (classinfo *) iptr->val.a;
3481 superindex = super->index;
3482 supervftbl = super->vftbl;
3485 #if defined(ENABLE_THREADS)
3486 codegen_threadcritrestart(cd, cd->mcodeptr - cd->mcodebase);
3489 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3490 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3492 M_MOV(s1, REG_ITMP1);
3496 /* calculate interface instanceof code size */
3500 s2 += (opt_showdisassemble ? 2 : 0);
3502 /* calculate class instanceof code size */
3506 s3 += (opt_showdisassemble ? 2 : 0);
3510 /* if class is not resolved, check which code to call */
3513 M_BEQZ(s1, 5 + (opt_showdisassemble ? 2 : 0) + s2 + 2 + s3);
3516 disp = dseg_adds4(cd, 0); /* super->flags */
3518 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3519 (constant_classref *) iptr->target, disp);
3521 if (opt_showdisassemble) {
3525 /* XXX TWISTI M_ILD can be 2 instructions long (jump offset) */
3526 M_ILD(REG_ITMP3, REG_PV, disp);
3527 M_AND_IMM(REG_ITMP3, ACC_INTERFACE, REG_ITMP3);
3528 M_BEQZ(REG_ITMP3, 1 + s2 + 2);
3532 /* interface instanceof code */
3534 if (!super || (super->flags & ACC_INTERFACE)) {
3540 codegen_addpatchref(cd,
3541 PATCHER_checkcast_instanceof_interface,
3542 (constant_classref *) iptr->target, 0);
3544 if (opt_showdisassemble) {
3549 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3550 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3551 M_IADD_IMM(REG_ITMP3, -superindex, REG_ITMP3);
3552 M_BLEZ(REG_ITMP3, 3);
3554 M_ALD(REG_ITMP1, REG_ITMP1,
3555 OFFSET(vftbl_t, interfacetable[0]) -
3556 superindex * sizeof(methodptr*));
3557 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3565 /* class instanceof code */
3567 if (!super || !(super->flags & ACC_INTERFACE)) {
3568 disp = dseg_addaddress(cd, supervftbl);
3575 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3576 (constant_classref *) iptr->target,
3579 if (opt_showdisassemble) {
3584 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3585 M_ALD(REG_ITMP2, REG_PV, disp);
3586 #if defined(ENABLE_THREADS)
3587 codegen_threadcritstart(cd, cd->mcodeptr - cd->mcodebase);
3589 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3590 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3591 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3592 #if defined(ENABLE_THREADS)
3593 codegen_threadcritstop(cd, cd->mcodeptr - cd->mcodebase);
3595 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3596 M_CMPULT(REG_ITMP2, REG_ITMP1, d);
3599 emit_store(jd, iptr, iptr->dst, d);
3603 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3604 /* op1 = dimension, val.a = class */
3606 /* check for negative sizes and copy sizes to stack if necessary */
3608 MCODECHECK((iptr->op1 << 1) + 64);
3610 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3611 /* copy SAVEDVAR sizes to stack */
3613 if (src->varkind != ARGVAR) {
3614 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3615 M_LST(s2, REG_SP, s1 * 8);
3619 /* a0 = dimension count */
3621 ICONST(rd->argintregs[0], iptr->op1);
3623 /* is patcher function set? */
3625 if (iptr->val.a == NULL) {
3626 disp = dseg_addaddress(cd, NULL);
3628 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3629 (constant_classref *) iptr->target, disp);
3631 if (opt_showdisassemble) {
3636 disp = dseg_addaddress(cd, iptr->val.a);
3639 /* a1 = arraydescriptor */
3641 M_ALD(rd->argintregs[1], REG_PV, disp);
3643 /* a2 = pointer to dimensions = stack pointer */
3645 M_INTMOVE(REG_SP, rd->argintregs[2]);
3647 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3648 M_ALD(REG_ITMP3, REG_PV, disp);
3649 M_JSR(REG_RA, REG_ITMP3);
3652 /* check for exception before result assignment */
3654 M_BEQZ(REG_RESULT, 0);
3655 codegen_add_fillinstacktrace_ref(cd);
3658 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3659 M_INTMOVE(REG_RESULT, d);
3660 emit_store(jd, iptr, iptr->dst, d);
3664 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
3668 } /* for instruction */
3670 /* copy values to interface registers */
3672 src = bptr->outstack;
3673 len = bptr->outdepth;
3675 #if defined(ENABLE_LSRA)
3680 if ((src->varkind != STACKVAR)) {
3682 if (IS_FLT_DBL_TYPE(s2)) {
3683 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
3684 if (rd->interfaces[len][s2].flags & INMEMORY) {
3685 if (IS_2_WORD_TYPE(s2))
3686 M_DST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3688 M_FST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3691 if (IS_2_WORD_TYPE(s2))
3692 M_DMOV(s1, rd->interfaces[len][s2].regoff);
3694 M_FMOV(s1, rd->interfaces[len][s2].regoff);
3698 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3699 if (rd->interfaces[len][s2].flags & INMEMORY)
3700 M_LST(s1, REG_SP, rd->interfaces[len][s2].regoff * 8);
3702 M_INTMOVE(s1, rd->interfaces[len][s2].regoff);
3708 /* At the end of a basic block we may have to append some nops,
3709 because the patcher stub calling code might be longer than the
3710 actual instruction. So codepatching does not change the
3711 following block unintentionally. */
3713 if (cd->mcodeptr < cd->lastmcodeptr) {
3714 while (cd->mcodeptr < cd->lastmcodeptr)
3718 } /* if (bptr -> flags >= BBREACHED) */
3719 } /* for basic block */
3721 dseg_createlinenumbertable(cd);
3724 /* generate exception and patcher stubs */
3733 savedmcodeptr = NULL;
3735 /* generate exception stubs */
3737 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3738 gen_resolvebranch(cd->mcodebase + eref->branchpos,
3739 eref->branchpos, cd->mcodeptr - cd->mcodebase);
3743 /* Check if the exception is an
3744 ArrayIndexOutOfBoundsException. If so, move index register
3747 if (eref->reg != -1)
3748 M_MOV(eref->reg, REG_ITMP1);
3750 /* calcuate exception address */
3752 M_LDA(REG_ITMP2_XPC, REG_PV, eref->branchpos - 4);
3754 /* move function to call into REG_ITMP3 */
3756 disp = dseg_addaddress(cd, eref->function);
3757 M_ALD(REG_ITMP3, REG_PV, disp);
3759 if (savedmcodeptr != NULL) {
3760 disp = ((u4 *) savedmcodeptr) - (((u4 *) cd->mcodeptr) + 1);
3765 savedmcodeptr = cd->mcodeptr;
3767 M_MOV(REG_PV, rd->argintregs[0]);
3768 M_MOV(REG_SP, rd->argintregs[1]);
3770 if (m->isleafmethod)
3771 M_MOV(REG_RA, rd->argintregs[2]);
3773 M_ALD(rd->argintregs[2],
3774 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3776 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3777 M_MOV(REG_ITMP1, rd->argintregs[4]);
3779 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3780 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3782 if (m->isleafmethod)
3783 M_AST(REG_RA, REG_SP, 1 * 8);
3785 M_JSR(REG_RA, REG_ITMP3);
3787 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3789 if (m->isleafmethod)
3790 M_ALD(REG_RA, REG_SP, 1 * 8);
3792 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3793 M_AADD_IMM(REG_SP, 2 * 8, REG_SP);
3795 a = dseg_addaddress(cd, asm_handle_exception);
3796 M_ALD(REG_ITMP3, REG_PV, a);
3803 /* generate code patching stub call code */
3805 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3806 /* check code segment size */
3810 /* Get machine code which is patched back in later. The
3811 call is 2 instruction words long. */
3813 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
3815 /* We need to split this, because an unaligned 8 byte read
3816 causes a SIGSEGV. */
3818 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
3819 ((u4 *) tmpmcodeptr)[0];
3821 /* Patch in the call to call the following code (done at
3824 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3825 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
3827 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
3829 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3831 new_internalerror("Jump offset is out of range: %d > +/-%d",
3839 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
3841 /* create stack frame */
3843 M_ASUB_IMM(REG_SP, 6 * 8, REG_SP);
3845 /* calculate return address and move it onto the stack */
3847 M_LDA(REG_ITMP3, REG_PV, pref->branchpos);
3848 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3850 /* move pointer to java_objectheader onto stack */
3852 #if defined(ENABLE_THREADS)
3853 /* create a virtual java_objectheader */
3855 (void) dseg_addaddress(cd, NULL); /* flcword */
3856 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
3857 disp = dseg_addaddress(cd, NULL); /* vftbl */
3859 M_LDA(REG_ITMP3, REG_PV, disp);
3860 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3865 /* move machine code onto stack */
3867 disp = dseg_adds8(cd, mcode);
3868 M_LLD(REG_ITMP3, REG_PV, disp);
3869 M_LST(REG_ITMP3, REG_SP, 3 * 8);
3871 /* move class/method/field reference onto stack */
3873 disp = dseg_addaddress(cd, pref->ref);
3874 M_ALD(REG_ITMP3, REG_PV, disp);
3875 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3877 /* move data segment displacement onto stack */
3879 disp = dseg_adds4(cd, pref->disp);
3880 M_ILD(REG_ITMP3, REG_PV, disp);
3881 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3883 /* move patcher function pointer onto stack */
3885 disp = dseg_addaddress(cd, pref->patcher);
3886 M_ALD(REG_ITMP3, REG_PV, disp);
3887 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3889 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3890 M_ALD(REG_ITMP3, REG_PV, disp);
3895 /* generate replacement-out stubs */
3900 replacementpoint = jd->code->rplpoints;
3902 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3903 /* check code segment size */
3907 /* note start of stub code */
3909 replacementpoint->outcode = (u1*) (ptrint) (cd->mcodeptr - cd->mcodebase);
3911 /* make machine code for patching */
3913 savedmcodeptr = cd->mcodeptr;
3914 cd->mcodeptr = (u1 *) &(replacementpoint->mcode);
3916 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3917 if ((disp < (s4) 0xffff8000) || (disp > (s4) 0x00007fff)) {
3919 new_internalerror("Jump offset is out of range: %d > +/-%d",
3924 M_NOP; /* delay slot */
3926 cd->mcodeptr = savedmcodeptr;
3928 /* create stack frame - 16-byte aligned */
3930 M_ASUB_IMM(REG_SP, 2 * 8, REG_SP);
3932 /* push address of `rplpoint` struct */
3934 disp = dseg_addaddress(cd, replacementpoint);
3935 M_ALD(REG_ITMP3, REG_PV, disp);
3936 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3938 /* jump to replacement function */
3940 disp = dseg_addaddress(cd, asm_replacement_out);
3941 M_ALD(REG_ITMP3, REG_PV, disp);
3943 M_NOP; /* delay slot */
3950 /* everything's ok */
3956 /* createcompilerstub **********************************************************
3958 Creates a stub routine which calls the compiler.
3960 *******************************************************************************/
3962 #define COMPILERSTUB_DATASIZE 3 * SIZEOF_VOID_P
3963 #define COMPILERSTUB_CODESIZE 4 * 4
3965 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3968 u1 *createcompilerstub(methodinfo *m)
3970 u1 *s; /* memory to hold the stub */
3976 s = CNEW(u1, COMPILERSTUB_SIZE);
3978 /* set data pointer and code pointer */
3981 s = s + COMPILERSTUB_DATASIZE;
3983 /* mark start of dump memory area */
3985 dumpsize = dump_size();
3987 cd = DNEW(codegendata);
3990 /* Store the codeinfo pointer in the same place as in the
3991 methodheader for compiled methods. */
3993 code = code_codeinfo_new(m);
3995 d[0] = (ptrint) asm_call_jit_compiler;
3997 d[2] = (ptrint) code;
3999 M_ALD_INTERN(REG_ITMP1, REG_PV, -2 * SIZEOF_VOID_P); /* codeinfo pointer */
4000 M_ALD_INTERN(REG_PV, REG_PV, -3 * SIZEOF_VOID_P); /* pointer to compiler */
4004 md_cacheflush(s, (s4) (cd->mcodeptr - (u1 *) d));
4006 #if defined(ENABLE_STATISTICS)
4008 count_cstub_len += COMPILERSTUB_SIZE;
4011 /* release dump area */
4013 dump_release(dumpsize);
4019 /* createnativestub ************************************************************
4021 Creates a stub routine which calls a native method.
4023 *******************************************************************************/
4025 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4031 s4 stackframesize; /* size of stackframe if needed */
4034 s4 i, j; /* count variables */
4037 s4 funcdisp; /* displacement of the function */
4039 /* get required compiler data */
4046 /* initialize variables */
4049 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4051 /* calculate stack frame size */
4054 1 + /* return address */
4055 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4056 sizeof(localref_table) / SIZEOF_VOID_P +
4057 md->paramcount + /* for saving arguments over calls */
4058 1 + /* for saving return address */
4061 /* create method header */
4063 #if SIZEOF_VOID_P == 4
4064 (void) dseg_addaddress(cd, code); /* CodeinfoPointer */
4066 (void) dseg_addaddress(cd, code); /* MethodPointer */
4067 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4068 (void) dseg_adds4(cd, 0); /* IsSync */
4069 (void) dseg_adds4(cd, 0); /* IsLeaf */
4070 (void) dseg_adds4(cd, 0); /* IntSave */
4071 (void) dseg_adds4(cd, 0); /* FltSave */
4072 (void) dseg_addlinenumbertablesize(cd);
4073 (void) dseg_adds4(cd, 0); /* ExTableSize */
4075 /* generate stub code */
4077 M_LDA(REG_SP, REG_SP, -stackframesize * 8); /* build up stackframe */
4078 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* store ra */
4080 /* call trace function */
4082 if (opt_verbosecall) {
4083 M_LDA(REG_SP, REG_SP, -(1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4085 /* save integer argument registers */
4087 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4088 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4089 M_LST(rd->argintregs[i], REG_SP, (1 + i) * 8);
4091 /* save and copy float arguments into integer registers */
4093 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4094 t = md->paramtypes[i].type;
4096 if (IS_FLT_DBL_TYPE(t)) {
4097 if (IS_2_WORD_TYPE(t)) {
4098 M_DST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4099 M_LLD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4101 M_FST(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4102 M_ILD(rd->argintregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4107 disp = dseg_addaddress(cd, m);
4108 M_ALD(REG_ITMP1, REG_PV, disp);
4109 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4110 disp = dseg_addaddress(cd, builtin_trace_args);
4111 M_ALD(REG_ITMP3, REG_PV, disp);
4112 M_JSR(REG_RA, REG_ITMP3);
4115 for (i = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4116 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4117 M_LLD(rd->argintregs[i], REG_SP, (1 + i) * 8);
4119 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4120 t = md->paramtypes[i].type;
4122 if (IS_FLT_DBL_TYPE(t)) {
4123 if (IS_2_WORD_TYPE(t))
4124 M_DLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4126 M_FLD(rd->argfltregs[i], REG_SP, (1 + INT_ARG_CNT + i) * 8);
4130 M_LDA(REG_SP, REG_SP, (1 + INT_ARG_CNT + FLT_ARG_CNT) * 8);
4133 /* get function address (this must happen before the stackframeinfo) */
4135 funcdisp = dseg_addaddress(cd, f);
4137 #if !defined(WITH_STATIC_CLASSPATH)
4139 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4141 if (opt_showdisassemble) {
4147 /* save integer and float argument registers */
4149 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4150 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4151 M_LST(rd->argintregs[i], REG_SP, j * 8);
4156 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4157 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4158 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4163 /* prepare data structures for native function call */
4165 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4166 M_MOV(REG_PV, rd->argintregs[1]);
4167 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4168 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4169 disp = dseg_addaddress(cd, codegen_start_native_call);
4170 M_ALD(REG_ITMP3, REG_PV, disp);
4171 M_JSR(REG_RA, REG_ITMP3);
4172 M_NOP; /* XXX fill me! */
4174 /* restore integer and float argument registers */
4176 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4177 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4178 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4183 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4184 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4185 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4190 /* copy or spill arguments to new locations */
4192 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4193 t = md->paramtypes[i].type;
4195 if (IS_INT_LNG_TYPE(t)) {
4196 if (!md->params[i].inmemory) {
4197 s1 = rd->argintregs[md->params[i].regoff];
4199 if (!nmd->params[j].inmemory) {
4200 s2 = rd->argintregs[nmd->params[j].regoff];
4203 s2 = nmd->params[j].regoff;
4204 M_AST(s1, REG_SP, s2 * 8);
4208 s1 = md->params[i].regoff + stackframesize;
4209 s2 = nmd->params[j].regoff;
4210 M_ALD(REG_ITMP1, REG_SP, s1 * 8);
4211 M_AST(REG_ITMP1, REG_SP, s2 * 8);
4215 if (!md->params[i].inmemory) {
4216 s1 = rd->argfltregs[md->params[i].regoff];
4218 if (!nmd->params[j].inmemory) {
4219 s2 = rd->argfltregs[nmd->params[j].regoff];
4220 if (IS_2_WORD_TYPE(t))
4226 s2 = nmd->params[j].regoff;
4227 if (IS_2_WORD_TYPE(t))
4228 M_DST(s1, REG_SP, s2 * 8);
4230 M_FST(s1, REG_SP, s2 * 8);
4234 s1 = md->params[i].regoff + stackframesize;
4235 s2 = nmd->params[j].regoff;
4236 if (IS_2_WORD_TYPE(t)) {
4237 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4238 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4240 M_FLD(REG_FTMP1, REG_SP, s1 * 8);
4241 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4247 /* put class into second argument register */
4249 if (m->flags & ACC_STATIC) {
4250 disp = dseg_addaddress(cd, m->class);
4251 M_ALD(rd->argintregs[1], REG_PV, disp);
4254 /* put env into first argument register */
4256 disp = dseg_addaddress(cd, _Jv_env);
4257 M_ALD(rd->argintregs[0], REG_PV, disp);
4259 /* do the native function call */
4261 M_ALD(REG_ITMP3, REG_PV, funcdisp); /* load adress of native method */
4262 M_JSR(REG_RA, REG_ITMP3); /* call native method */
4263 M_NOP; /* delay slot */
4265 /* save return value */
4267 if (IS_INT_LNG_TYPE(md->returntype.type))
4268 M_LST(REG_RESULT, REG_SP, 0 * 8);
4270 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4272 /* remove native stackframe info */
4274 M_AADD_IMM(REG_SP, stackframesize * 8 - SIZEOF_VOID_P, rd->argintregs[0]);
4275 disp = dseg_addaddress(cd, codegen_finish_native_call);
4276 M_ALD(REG_ITMP3, REG_PV, disp);
4277 M_JSR(REG_RA, REG_ITMP3);
4278 M_NOP; /* XXX fill me! */
4280 /* call finished trace function */
4282 if (opt_verbosecall) {
4283 if (IS_INT_LNG_TYPE(md->returntype.type))
4284 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4286 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4288 disp = dseg_addaddress(cd, m);
4289 M_ALD(rd->argintregs[0], REG_PV, disp);
4291 M_MOV(REG_RESULT, rd->argintregs[1]);
4292 M_DMFC1(REG_ITMP1, REG_FRESULT);
4293 M_DMTC1(REG_ITMP1, rd->argfltregs[2]);
4294 M_DMTC1(REG_ITMP1, rd->argfltregs[3]);
4296 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4297 M_ALD(REG_ITMP3, REG_PV, disp);
4298 M_JSR(REG_RA, REG_ITMP3);
4302 /* check for exception */
4304 #if defined(ENABLE_THREADS)
4305 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4306 M_ALD(REG_ITMP3, REG_PV, disp);
4307 M_JSR(REG_RA, REG_ITMP3);
4309 M_MOV(REG_RESULT, REG_ITMP3);
4311 disp = dseg_addaddress(cd, &_exceptionptr);
4312 M_ALD(REG_ITMP3, REG_PV, disp); /* get address of exceptionptr */
4314 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4316 M_ALD(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P); /* load ra */
4318 /* restore return value */
4320 if (IS_INT_LNG_TYPE(md->returntype.type))
4321 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4323 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4325 M_BNEZ(REG_ITMP1, 2); /* if no exception then return */
4326 M_LDA(REG_SP, REG_SP, stackframesize * 8);/* remove stackframe, DELAY SLOT*/
4328 M_RET(REG_RA); /* return to caller */
4329 M_NOP; /* DELAY SLOT */
4331 /* handle exception */
4333 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4335 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4336 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4337 M_JMP(REG_ITMP3); /* jump to asm exception handler */
4338 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4341 /* generate static stub call code */
4349 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4350 /* Get machine code which is patched back in later. The
4351 call is 2 instruction words long. */
4353 tmpmcodeptr = (u1 *) (cd->mcodebase + pref->branchpos);
4355 /* We need to split this, because an unaligned 8 byte read
4356 causes a SIGSEGV. */
4358 mcode = ((u8) ((u4 *) tmpmcodeptr)[1] << 32) +
4359 ((u4 *) tmpmcodeptr)[0];
4361 /* Patch in the call to call the following code (done at
4364 savedmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4365 cd->mcodeptr = tmpmcodeptr; /* set mcodeptr to patch position */
4367 disp = ((u4 *) savedmcodeptr) - (((u4 *) tmpmcodeptr) + 1);
4369 M_NOP; /* branch delay slot */
4371 cd->mcodeptr = savedmcodeptr; /* restore the current mcodeptr */
4373 /* create stack frame */
4375 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4377 /* move return address onto stack */
4379 M_AST(REG_RA, REG_SP, 5 * 8);
4381 /* move pointer to java_objectheader onto stack */
4383 #if defined(ENABLE_THREADS)
4384 /* order reversed because of data segment layout */
4386 (void) dseg_addaddress(cd, NULL); /* flcword */
4387 (void) dseg_addaddress(cd, lock_get_initial_lock_word()); /* monitorPtr */
4388 disp = dseg_addaddress(cd, NULL); /* vftbl */
4390 M_LDA(REG_ITMP3, REG_PV, disp);
4391 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4393 M_AST(REG_ZERO, REG_SP, 4 * 8);
4396 /* move machine code onto stack */
4398 disp = dseg_adds8(cd, mcode);
4399 M_LLD(REG_ITMP3, REG_PV, disp);
4400 M_LST(REG_ITMP3, REG_SP, 3 * 8);
4402 /* move class/method/field reference onto stack */
4404 disp = dseg_addaddress(cd, pref->ref);
4405 M_ALD(REG_ITMP3, REG_PV, disp);
4406 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4408 /* move data segment displacement onto stack */
4410 disp = dseg_adds4(cd, pref->disp);
4411 M_ILD(REG_ITMP3, REG_PV, disp);
4412 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4414 /* move patcher function pointer onto stack */
4416 disp = dseg_addaddress(cd, pref->patcher);
4417 M_ALD(REG_ITMP3, REG_PV, disp);
4418 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4420 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4421 M_ALD(REG_ITMP3, REG_PV, disp);
4429 return jd->code->entrypoint;
4434 * These are local overrides for various environment variables in Emacs.
4435 * Please do not remove this and leave it at the end of the file, where
4436 * Emacs will automagically detect them.
4437 * ---------------------------------------------------------------------
4440 * indent-tabs-mode: t
4444 * vim:noexpandtab:sw=4:ts=4: