1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
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: Joseph Wenninger
35 $Id: codegen.c 4826 2006-04-24 16:06:16Z twisti $
50 #include "vm/jit/alpha/arch.h"
51 #include "vm/jit/alpha/codegen.h"
53 #include "native/jni.h"
54 #include "native/native.h"
55 #include "vm/builtin.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/loader.h"
59 #include "vm/options.h"
60 #include "vm/stringlocal.h"
62 #include "vm/jit/asmpart.h"
63 #include "vm/jit/codegen-common.h"
64 #include "vm/jit/dseg.h"
65 #include "vm/jit/emit.h"
66 #include "vm/jit/jit.h"
67 #include "vm/jit/parse.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)
88 s4 len, s1, s2, s3, d, disp;
96 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
97 builtintable_entry *bte;
99 rplpoint *replacementpoint;
101 /* get required compiler data */
107 /* prevent compiler warnings */
118 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
120 /* space to save used callee saved registers */
122 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
123 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
125 stackframesize = rd->memuse + savedregs_num;
127 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
128 if (checksync && (m->flags & ACC_SYNCHRONIZED))
132 /* create method header */
135 stackframesize = (stackframesize + 1) & ~1; /* align stack to 16-bytes */
138 (void) dseg_addaddress(cd, m); /* MethodPointer */
139 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
141 #if defined(USE_THREADS)
142 /* IsSync contains the offset relative to the stack pointer for the
143 argument of monitor_exit used in the exception handler. Since the
144 offset could be zero and give a wrong meaning of the flag it is
148 if (checksync && (m->flags & ACC_SYNCHRONIZED))
149 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
152 (void) dseg_adds4(cd, 0); /* IsSync */
154 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
155 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
156 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
158 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, -stackframesize * 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_LST(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);
208 } else { /* reg arg -> spilled */
209 M_LST(s2, REG_SP, var->regoff * 8);
212 } else { /* stack arguments */
213 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
214 M_LLD(var->regoff, REG_SP, (stackframesize + s1) * 8);
216 } else { /* stack arg -> spilled */
217 var->regoff = stackframesize + s1;
221 } else { /* floating args */
222 if (!md->params[p].inmemory) { /* register arguments */
223 s2 = rd->argfltregs[s1];
224 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
225 M_FLTMOVE(s2, var->regoff);
227 } else { /* reg arg -> spilled */
228 M_DST(s2, REG_SP, var->regoff * 8);
231 } else { /* stack arguments */
232 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
233 M_DLD(var->regoff, REG_SP, (stackframesize + s1) * 8);
235 } else { /* stack-arg -> spilled */
236 var->regoff = stackframesize + s1;
242 /* call monitorenter function */
244 #if defined(USE_THREADS)
245 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
246 /* stack offset for monitor argument */
251 if (opt_verbosecall) {
252 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
254 for (p = 0; p < INT_ARG_CNT; p++)
255 M_LST(rd->argintregs[p], REG_SP, p * 8);
257 for (p = 0; p < FLT_ARG_CNT; p++)
258 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
260 s1 += INT_ARG_CNT + FLT_ARG_CNT;
262 #endif /* !defined(NDEBUG) */
264 /* decide which monitor enter function to call */
266 if (m->flags & ACC_STATIC) {
267 disp = dseg_addaddress(cd, m->class);
268 M_ALD(rd->argintregs[0], REG_PV, disp);
269 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
270 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
271 M_ALD(REG_PV, REG_PV, disp);
272 M_JSR(REG_RA, REG_PV);
273 disp = -(s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
274 M_LDA(REG_PV, REG_RA, disp);
277 M_BEQZ(rd->argintregs[0], 0);
278 codegen_add_nullpointerexception_ref(cd);
279 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
280 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
281 M_ALD(REG_PV, REG_PV, disp);
282 M_JSR(REG_RA, REG_PV);
283 disp = -(s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
284 M_LDA(REG_PV, REG_RA, disp);
288 if (opt_verbosecall) {
289 for (p = 0; p < INT_ARG_CNT; p++)
290 M_LLD(rd->argintregs[p], REG_SP, p * 8);
292 for (p = 0; p < FLT_ARG_CNT; p++)
293 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
295 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
297 #endif /* !defined(NDEBUG) */
301 /* call trace function */
304 if (opt_verbosecall) {
305 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
306 M_AST(REG_RA, REG_SP, 1 * 8);
308 /* save integer argument registers */
310 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
311 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
313 /* save and copy float arguments into integer registers */
315 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
316 t = md->paramtypes[p].type;
318 if (IS_FLT_DBL_TYPE(t)) {
319 if (IS_2_WORD_TYPE(t)) {
320 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
323 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
326 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
329 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
333 disp = dseg_addaddress(cd, m);
334 M_ALD(REG_ITMP1, REG_PV, disp);
335 M_AST(REG_ITMP1, REG_SP, 0 * 8);
336 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
337 M_ALD(REG_PV, REG_PV, disp);
338 M_JSR(REG_RA, REG_PV);
339 disp = -(s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
340 M_LDA(REG_PV, REG_RA, disp);
341 M_ALD(REG_RA, REG_SP, 1 * 8);
343 /* restore integer argument registers */
345 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
346 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
348 /* restore float argument registers */
350 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
351 t = md->paramtypes[p].type;
353 if (IS_FLT_DBL_TYPE(t)) {
354 if (IS_2_WORD_TYPE(t)) {
355 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
358 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
362 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
366 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
368 #endif /* !defined(NDEBUG) */
372 /* end of header generation */
374 replacementpoint = jd->code->rplpoints;
376 /* walk through all basic blocks */
378 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
380 bptr->mpc = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
382 if (bptr->flags >= BBREACHED) {
384 /* branch resolving */
388 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
389 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
390 brefs->branchpos, bptr->mpc);
394 /* handle replacement points */
396 if (bptr->bitflags & BBFLAG_REPLACEMENT) {
397 replacementpoint->pc = (u1*)(ptrint)bptr->mpc; /* will be resolved later */
402 /* copy interface registers to their destination */
407 #if defined(ENABLE_LSRA)
409 while (src != NULL) {
411 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
412 /* d = reg_of_var(m, src, REG_ITMP1); */
413 if (!(src->flags & INMEMORY))
417 M_INTMOVE(REG_ITMP1, d);
418 emit_store(jd, NULL, src, d);
424 while (src != NULL) {
426 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
427 d = codegen_reg_of_var(rd, 0, src, REG_ITMP1);
428 M_INTMOVE(REG_ITMP1, d);
429 emit_store(jd, NULL, src, d);
432 d = codegen_reg_of_var(rd, 0, src, REG_IFTMP);
433 if ((src->varkind != STACKVAR)) {
435 if (IS_FLT_DBL_TYPE(s2)) {
436 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
437 s1 = rd->interfaces[len][s2].regoff;
440 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
442 emit_store(jd, NULL, src, d);
445 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
446 s1 = rd->interfaces[len][s2].regoff;
449 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
451 emit_store(jd, NULL, src, d);
457 #if defined(ENABLE_LSRA)
461 /* walk through all instructions */
466 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
467 if (iptr->line != currentline) {
468 dseg_addlinenumber(cd, iptr->line);
469 currentline = iptr->line;
472 MCODECHECK(64); /* an instruction usually needs < 64 words */
475 case ICMD_INLINE_START:
476 case ICMD_INLINE_END:
479 case ICMD_NOP: /* ... ==> ... */
482 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
484 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
486 codegen_add_nullpointerexception_ref(cd);
489 /* constant operations ************************************************/
491 case ICMD_ICONST: /* ... ==> ..., constant */
492 /* op1 = 0, val.i = constant */
494 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
495 ICONST(d, iptr->val.i);
496 emit_store(jd, iptr, iptr->dst, d);
499 case ICMD_LCONST: /* ... ==> ..., constant */
500 /* op1 = 0, val.l = constant */
502 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
503 LCONST(d, iptr->val.l);
504 emit_store(jd, iptr, iptr->dst, d);
507 case ICMD_FCONST: /* ... ==> ..., constant */
508 /* op1 = 0, val.f = constant */
510 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
511 disp = dseg_addfloat(cd, iptr->val.f);
512 M_FLD(d, REG_PV, disp);
513 emit_store(jd, iptr, iptr->dst, d);
516 case ICMD_DCONST: /* ... ==> ..., constant */
517 /* op1 = 0, val.d = constant */
519 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
520 disp = dseg_adddouble(cd, iptr->val.d);
521 M_DLD(d, REG_PV, disp);
522 emit_store(jd, iptr, iptr->dst, d);
525 case ICMD_ACONST: /* ... ==> ..., constant */
526 /* op1 = 0, val.a = constant */
528 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
530 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
531 disp = dseg_addaddress(cd, iptr->val.a);
533 codegen_addpatchref(cd, PATCHER_aconst,
534 (unresolved_class *) iptr->target, disp);
536 if (opt_showdisassemble)
539 M_ALD(d, REG_PV, disp);
542 if (iptr->val.a == NULL) {
543 M_INTMOVE(REG_ZERO, d);
545 disp = dseg_addaddress(cd, iptr->val.a);
546 M_ALD(d, REG_PV, disp);
549 emit_store(jd, iptr, iptr->dst, d);
553 /* load/store operations **********************************************/
555 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
556 case ICMD_LLOAD: /* op1 = local variable */
559 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP1);
560 if ((iptr->dst->varkind == LOCALVAR) &&
561 (iptr->dst->varnum == iptr->op1))
563 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
564 if (var->flags & INMEMORY) {
565 M_LLD(d, REG_SP, var->regoff * 8);
567 M_INTMOVE(var->regoff, d);
569 emit_store(jd, iptr, iptr->dst, d);
572 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
573 case ICMD_DLOAD: /* op1 = local variable */
575 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
576 if ((iptr->dst->varkind == LOCALVAR) &&
577 (iptr->dst->varnum == iptr->op1))
579 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
580 if (var->flags & INMEMORY) {
581 M_DLD(d, REG_SP, var->regoff * 8);
583 M_FLTMOVE(var->regoff, d);
585 emit_store(jd, iptr, iptr->dst, d);
589 case ICMD_ISTORE: /* ..., value ==> ... */
590 case ICMD_LSTORE: /* op1 = local variable */
593 if ((src->varkind == LOCALVAR) &&
594 (src->varnum == iptr->op1))
596 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
597 if (var->flags & INMEMORY) {
598 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
599 M_LST(s1, REG_SP, var->regoff * 8);
601 s1 = emit_load_s1(jd, iptr, src, var->regoff);
602 M_INTMOVE(s1, var->regoff);
606 case ICMD_FSTORE: /* ..., value ==> ... */
607 case ICMD_DSTORE: /* op1 = local variable */
609 if ((src->varkind == LOCALVAR) &&
610 (src->varnum == iptr->op1))
612 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
613 if (var->flags & INMEMORY) {
614 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
615 M_DST(s1, REG_SP, var->regoff * 8);
617 s1 = emit_load_s1(jd, iptr, src, var->regoff);
618 M_FLTMOVE(s1, var->regoff);
623 /* pop/dup/swap operations ********************************************/
625 /* attention: double and longs are only one entry in CACAO ICMDs */
627 case ICMD_POP: /* ..., value ==> ... */
628 case ICMD_POP2: /* ..., value, value ==> ... */
631 case ICMD_DUP: /* ..., a ==> ..., a, a */
632 M_COPY(src, iptr->dst);
635 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
637 M_COPY(src, iptr->dst);
638 M_COPY(src->prev, iptr->dst->prev);
639 M_COPY(iptr->dst, iptr->dst->prev->prev);
642 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
644 M_COPY(src, iptr->dst);
645 M_COPY(src->prev, iptr->dst->prev);
646 M_COPY(src->prev->prev, iptr->dst->prev->prev);
647 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
650 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
652 M_COPY(src, iptr->dst);
653 M_COPY(src->prev, iptr->dst->prev);
656 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
658 M_COPY(src, iptr->dst);
659 M_COPY(src->prev, iptr->dst->prev);
660 M_COPY(src->prev->prev, iptr->dst->prev->prev);
661 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
662 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
665 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
667 M_COPY(src, iptr->dst);
668 M_COPY(src->prev, iptr->dst->prev);
669 M_COPY(src->prev->prev, iptr->dst->prev->prev);
670 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
671 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
672 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
675 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
677 M_COPY(src, iptr->dst->prev);
678 M_COPY(src->prev, iptr->dst);
682 /* integer operations *************************************************/
684 case ICMD_INEG: /* ..., value ==> ..., - value */
686 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
687 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
688 M_ISUB(REG_ZERO, s1, d);
689 emit_store(jd, iptr, iptr->dst, d);
692 case ICMD_LNEG: /* ..., value ==> ..., - value */
694 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
695 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
696 M_LSUB(REG_ZERO, s1, d);
697 emit_store(jd, iptr, iptr->dst, d);
700 case ICMD_I2L: /* ..., value ==> ..., value */
702 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
703 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
705 emit_store(jd, iptr, iptr->dst, d);
708 case ICMD_L2I: /* ..., value ==> ..., value */
710 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
711 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
712 M_IADD(s1, REG_ZERO, d);
713 emit_store(jd, iptr, iptr->dst, d);
716 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
718 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
719 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
720 if (has_ext_instr_set) {
723 M_SLL_IMM(s1, 56, d);
724 M_SRA_IMM( d, 56, d);
726 emit_store(jd, iptr, iptr->dst, d);
729 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
731 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
732 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
734 emit_store(jd, iptr, iptr->dst, d);
737 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
739 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
740 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
741 if (has_ext_instr_set) {
744 M_SLL_IMM(s1, 48, d);
745 M_SRA_IMM( d, 48, d);
747 emit_store(jd, iptr, iptr->dst, d);
751 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
753 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
754 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
755 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
757 emit_store(jd, iptr, iptr->dst, d);
760 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
761 /* val.i = constant */
763 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
764 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
765 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
766 M_IADD_IMM(s1, iptr->val.i, d);
768 ICONST(REG_ITMP2, iptr->val.i);
769 M_IADD(s1, REG_ITMP2, d);
771 emit_store(jd, iptr, iptr->dst, d);
774 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
776 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
777 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
778 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
780 emit_store(jd, iptr, iptr->dst, d);
783 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
784 /* val.l = constant */
786 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
787 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
788 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
789 M_LADD_IMM(s1, iptr->val.l, d);
791 LCONST(REG_ITMP2, iptr->val.l);
792 M_LADD(s1, REG_ITMP2, d);
794 emit_store(jd, iptr, iptr->dst, d);
797 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
799 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
800 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
801 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
803 emit_store(jd, iptr, iptr->dst, d);
806 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
807 /* val.i = constant */
809 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
810 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
811 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
812 M_ISUB_IMM(s1, iptr->val.i, d);
814 ICONST(REG_ITMP2, iptr->val.i);
815 M_ISUB(s1, REG_ITMP2, d);
817 emit_store(jd, iptr, iptr->dst, d);
820 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
822 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
823 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
824 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
826 emit_store(jd, iptr, iptr->dst, d);
829 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
830 /* val.l = constant */
832 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
833 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
834 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
835 M_LSUB_IMM(s1, iptr->val.l, d);
837 LCONST(REG_ITMP2, iptr->val.l);
838 M_LSUB(s1, REG_ITMP2, d);
840 emit_store(jd, iptr, iptr->dst, d);
843 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
845 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
846 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
847 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
849 emit_store(jd, iptr, iptr->dst, d);
852 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
853 /* val.i = constant */
855 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
856 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
857 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
858 M_IMUL_IMM(s1, iptr->val.i, d);
860 ICONST(REG_ITMP2, iptr->val.i);
861 M_IMUL(s1, REG_ITMP2, d);
863 emit_store(jd, iptr, iptr->dst, d);
866 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
868 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
869 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
870 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
872 emit_store(jd, iptr, iptr->dst, d);
875 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
876 /* val.l = constant */
878 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
879 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
880 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
881 M_LMUL_IMM(s1, iptr->val.l, d);
883 LCONST(REG_ITMP2, iptr->val.l);
884 M_LMUL(s1, REG_ITMP2, d);
886 emit_store(jd, iptr, iptr->dst, d);
889 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
890 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
892 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
893 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
894 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
896 codegen_add_arithmeticexception_ref(cd);
898 M_MOV(s1, rd->argintregs[0]);
899 M_MOV(s2, rd->argintregs[1]);
901 disp = dseg_addaddress(cd, bte->fp);
902 M_ALD(REG_PV, REG_PV, disp);
903 M_JSR(REG_RA, REG_PV);
904 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
905 M_LDA(REG_PV, REG_RA, -disp);
907 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
908 emit_store(jd, iptr, iptr->dst, d);
911 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
912 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
914 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
915 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
916 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
918 codegen_add_arithmeticexception_ref(cd);
920 M_MOV(s1, rd->argintregs[0]);
921 M_MOV(s2, rd->argintregs[1]);
923 disp = dseg_addaddress(cd, bte->fp);
924 M_ALD(REG_PV, REG_PV, disp);
925 M_JSR(REG_RA, REG_PV);
926 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
927 M_LDA(REG_PV, REG_RA, -disp);
929 M_INTMOVE(REG_RESULT, d);
930 emit_store(jd, iptr, iptr->dst, d);
933 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
934 case ICMD_LDIVPOW2: /* val.i = constant */
936 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
937 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
938 if (iptr->val.i <= 15) {
939 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
940 M_CMOVGE(s1, s1, REG_ITMP2);
942 M_SRA_IMM(s1, 63, REG_ITMP2);
943 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
944 M_LADD(s1, REG_ITMP2, REG_ITMP2);
946 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
947 emit_store(jd, iptr, iptr->dst, d);
950 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
952 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
953 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
954 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
955 M_AND_IMM(s2, 0x1f, REG_ITMP3);
956 M_SLL(s1, REG_ITMP3, d);
957 M_IADD(d, REG_ZERO, d);
958 emit_store(jd, iptr, iptr->dst, d);
961 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
962 /* val.i = constant */
964 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
965 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
966 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
967 M_IADD(d, REG_ZERO, d);
968 emit_store(jd, iptr, iptr->dst, d);
971 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
973 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
974 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
975 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
976 M_AND_IMM(s2, 0x1f, REG_ITMP3);
977 M_SRA(s1, REG_ITMP3, d);
978 emit_store(jd, iptr, iptr->dst, d);
981 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
982 /* val.i = constant */
984 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
985 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
986 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
987 emit_store(jd, iptr, iptr->dst, d);
990 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
992 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
993 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
994 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
995 M_AND_IMM(s2, 0x1f, REG_ITMP2);
997 M_SRL(d, REG_ITMP2, d);
998 M_IADD(d, REG_ZERO, d);
999 emit_store(jd, iptr, iptr->dst, d);
1002 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
1003 /* val.i = constant */
1005 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1006 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1008 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
1009 M_IADD(d, REG_ZERO, d);
1010 emit_store(jd, iptr, iptr->dst, d);
1013 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
1015 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1016 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1017 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1019 emit_store(jd, iptr, iptr->dst, d);
1022 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1023 /* val.i = constant */
1025 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1026 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1027 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1028 emit_store(jd, iptr, iptr->dst, d);
1031 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1033 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1034 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1035 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1037 emit_store(jd, iptr, iptr->dst, d);
1040 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1041 /* val.i = constant */
1043 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1044 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1045 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1046 emit_store(jd, iptr, iptr->dst, d);
1049 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1051 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1052 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1053 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1055 emit_store(jd, iptr, iptr->dst, d);
1058 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1059 /* val.i = constant */
1061 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1062 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1063 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1064 emit_store(jd, iptr, iptr->dst, d);
1067 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1070 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1071 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1072 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1074 emit_store(jd, iptr, iptr->dst, d);
1077 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1078 /* val.i = constant */
1080 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1081 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1082 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1083 M_AND_IMM(s1, iptr->val.i, d);
1084 } else if (iptr->val.i == 0xffff) {
1086 } else if (iptr->val.i == 0xffffff) {
1087 M_ZAPNOT_IMM(s1, 0x07, d);
1089 ICONST(REG_ITMP2, iptr->val.i);
1090 M_AND(s1, REG_ITMP2, d);
1092 emit_store(jd, iptr, iptr->dst, d);
1095 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1096 /* val.i = constant */
1098 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1099 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1101 M_MOV(s1, REG_ITMP1);
1104 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1105 M_AND_IMM(s1, iptr->val.i, d);
1107 M_ISUB(REG_ZERO, s1, d);
1108 M_AND_IMM(d, iptr->val.i, d);
1109 } else if (iptr->val.i == 0xffff) {
1112 M_ISUB(REG_ZERO, s1, d);
1114 } else if (iptr->val.i == 0xffffff) {
1115 M_ZAPNOT_IMM(s1, 0x07, d);
1117 M_ISUB(REG_ZERO, s1, d);
1118 M_ZAPNOT_IMM(d, 0x07, d);
1120 ICONST(REG_ITMP2, iptr->val.i);
1121 M_AND(s1, REG_ITMP2, d);
1123 M_ISUB(REG_ZERO, s1, d);
1124 M_AND(d, REG_ITMP2, d);
1126 M_ISUB(REG_ZERO, d, d);
1127 emit_store(jd, iptr, iptr->dst, d);
1130 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1131 /* val.l = constant */
1133 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1134 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1135 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1136 M_AND_IMM(s1, iptr->val.l, d);
1137 } else if (iptr->val.l == 0xffffL) {
1139 } else if (iptr->val.l == 0xffffffL) {
1140 M_ZAPNOT_IMM(s1, 0x07, d);
1141 } else if (iptr->val.l == 0xffffffffL) {
1143 } else if (iptr->val.l == 0xffffffffffL) {
1144 M_ZAPNOT_IMM(s1, 0x1f, d);
1145 } else if (iptr->val.l == 0xffffffffffffL) {
1146 M_ZAPNOT_IMM(s1, 0x3f, d);
1147 } else if (iptr->val.l == 0xffffffffffffffL) {
1148 M_ZAPNOT_IMM(s1, 0x7f, d);
1150 LCONST(REG_ITMP2, iptr->val.l);
1151 M_AND(s1, REG_ITMP2, d);
1153 emit_store(jd, iptr, iptr->dst, d);
1156 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1157 /* val.l = constant */
1159 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1160 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1162 M_MOV(s1, REG_ITMP1);
1165 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1166 M_AND_IMM(s1, iptr->val.l, d);
1168 M_LSUB(REG_ZERO, s1, d);
1169 M_AND_IMM(d, iptr->val.l, d);
1170 } else if (iptr->val.l == 0xffffL) {
1173 M_LSUB(REG_ZERO, s1, d);
1175 } else if (iptr->val.l == 0xffffffL) {
1176 M_ZAPNOT_IMM(s1, 0x07, d);
1178 M_LSUB(REG_ZERO, s1, d);
1179 M_ZAPNOT_IMM(d, 0x07, d);
1180 } else if (iptr->val.l == 0xffffffffL) {
1183 M_LSUB(REG_ZERO, s1, d);
1185 } else if (iptr->val.l == 0xffffffffffL) {
1186 M_ZAPNOT_IMM(s1, 0x1f, d);
1188 M_LSUB(REG_ZERO, s1, d);
1189 M_ZAPNOT_IMM(d, 0x1f, d);
1190 } else if (iptr->val.l == 0xffffffffffffL) {
1191 M_ZAPNOT_IMM(s1, 0x3f, d);
1193 M_LSUB(REG_ZERO, s1, d);
1194 M_ZAPNOT_IMM(d, 0x3f, d);
1195 } else if (iptr->val.l == 0xffffffffffffffL) {
1196 M_ZAPNOT_IMM(s1, 0x7f, d);
1198 M_LSUB(REG_ZERO, s1, d);
1199 M_ZAPNOT_IMM(d, 0x7f, d);
1201 LCONST(REG_ITMP2, iptr->val.l);
1202 M_AND(s1, REG_ITMP2, d);
1204 M_LSUB(REG_ZERO, s1, d);
1205 M_AND(d, REG_ITMP2, d);
1207 M_LSUB(REG_ZERO, d, d);
1208 emit_store(jd, iptr, iptr->dst, d);
1211 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1214 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1215 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1216 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1218 emit_store(jd, iptr, iptr->dst, d);
1221 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1222 /* val.i = constant */
1224 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1225 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1226 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1227 M_OR_IMM(s1, iptr->val.i, d);
1229 ICONST(REG_ITMP2, iptr->val.i);
1230 M_OR(s1, REG_ITMP2, d);
1232 emit_store(jd, iptr, iptr->dst, d);
1235 case ICMD_LORCONST: /* ..., 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 <= 255)) {
1241 M_OR_IMM(s1, iptr->val.l, d);
1243 LCONST(REG_ITMP2, iptr->val.l);
1244 M_OR(s1, REG_ITMP2, d);
1246 emit_store(jd, iptr, iptr->dst, d);
1249 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1252 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1253 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1254 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1256 emit_store(jd, iptr, iptr->dst, d);
1259 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1260 /* val.i = constant */
1262 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1263 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1264 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1265 M_XOR_IMM(s1, iptr->val.i, d);
1267 ICONST(REG_ITMP2, iptr->val.i);
1268 M_XOR(s1, REG_ITMP2, d);
1270 emit_store(jd, iptr, iptr->dst, d);
1273 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1274 /* val.l = constant */
1276 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1277 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1278 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1279 M_XOR_IMM(s1, iptr->val.l, d);
1281 LCONST(REG_ITMP2, iptr->val.l);
1282 M_XOR(s1, REG_ITMP2, d);
1284 emit_store(jd, iptr, iptr->dst, d);
1288 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1290 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1291 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1292 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1293 M_CMPLT(s1, s2, REG_ITMP3);
1294 M_CMPLT(s2, s1, REG_ITMP1);
1295 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1296 emit_store(jd, iptr, iptr->dst, d);
1300 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1301 /* op1 = variable, val.i = constant */
1303 var = &(rd->locals[iptr->op1][TYPE_INT]);
1304 if (var->flags & INMEMORY) {
1306 M_LLD(s1, REG_SP, var->regoff * 8);
1309 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1310 M_IADD_IMM(s1, iptr->val.i, s1);
1311 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1312 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1314 M_LDA (s1, s1, iptr->val.i);
1315 M_IADD(s1, REG_ZERO, s1);
1317 if (var->flags & INMEMORY)
1318 M_LST(s1, REG_SP, var->regoff * 8);
1322 /* floating operations ************************************************/
1324 case ICMD_FNEG: /* ..., value ==> ..., - value */
1326 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1327 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1329 emit_store(jd, iptr, iptr->dst, d);
1332 case ICMD_DNEG: /* ..., value ==> ..., - value */
1334 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1335 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1337 emit_store(jd, iptr, iptr->dst, d);
1340 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1342 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1343 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1344 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1348 if (d == s1 || d == s2) {
1349 M_FADDS(s1, s2, REG_FTMP3);
1351 M_FMOV(REG_FTMP3, d);
1357 emit_store(jd, iptr, iptr->dst, d);
1360 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1362 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1363 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1364 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1368 if (d == s1 || d == s2) {
1369 M_DADDS(s1, s2, REG_FTMP3);
1371 M_FMOV(REG_FTMP3, d);
1377 emit_store(jd, iptr, iptr->dst, d);
1380 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1382 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1383 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1384 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1388 if (d == s1 || d == s2) {
1389 M_FSUBS(s1, s2, REG_FTMP3);
1391 M_FMOV(REG_FTMP3, d);
1397 emit_store(jd, iptr, iptr->dst, d);
1400 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1402 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1403 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1404 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1408 if (d == s1 || d == s2) {
1409 M_DSUBS(s1, s2, REG_FTMP3);
1411 M_FMOV(REG_FTMP3, d);
1417 emit_store(jd, iptr, iptr->dst, d);
1420 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1422 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1423 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1424 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1428 if (d == s1 || d == s2) {
1429 M_FMULS(s1, s2, REG_FTMP3);
1431 M_FMOV(REG_FTMP3, d);
1437 emit_store(jd, iptr, iptr->dst, d);
1440 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1442 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1443 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1444 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1448 if (d == s1 || d == s2) {
1449 M_DMULS(s1, s2, REG_FTMP3);
1451 M_FMOV(REG_FTMP3, d);
1457 emit_store(jd, iptr, iptr->dst, d);
1460 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1462 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1463 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1464 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1468 if (d == s1 || d == s2) {
1469 M_FDIVS(s1, s2, REG_FTMP3);
1471 M_FMOV(REG_FTMP3, d);
1477 emit_store(jd, iptr, iptr->dst, d);
1480 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1482 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1483 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1484 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1488 if (d == s1 || d == s2) {
1489 M_DDIVS(s1, s2, REG_FTMP3);
1491 M_FMOV(REG_FTMP3, d);
1497 emit_store(jd, iptr, iptr->dst, d);
1500 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1502 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1503 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1504 disp = dseg_adddouble(cd, 0.0);
1505 M_LST(s1, REG_PV, disp);
1506 M_DLD(d, REG_PV, disp);
1508 emit_store(jd, iptr, iptr->dst, d);
1511 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1513 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1514 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1515 disp = dseg_adddouble(cd, 0.0);
1516 M_LST(s1, REG_PV, disp);
1517 M_DLD(d, REG_PV, disp);
1519 emit_store(jd, iptr, iptr->dst, d);
1522 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1524 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1525 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1526 disp = dseg_adddouble(cd, 0.0);
1527 M_CVTDL_C(s1, REG_FTMP2);
1528 M_CVTLI(REG_FTMP2, REG_FTMP3);
1529 M_DST(REG_FTMP3, REG_PV, disp);
1530 M_ILD(d, REG_PV, disp);
1531 emit_store(jd, iptr, iptr->dst, d);
1534 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1536 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1537 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1538 disp = dseg_adddouble(cd, 0.0);
1539 M_CVTDL_C(s1, REG_FTMP2);
1540 M_DST(REG_FTMP2, REG_PV, disp);
1541 M_LLD(d, REG_PV, disp);
1542 emit_store(jd, iptr, iptr->dst, d);
1545 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1547 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1548 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1551 emit_store(jd, iptr, iptr->dst, d);
1554 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1556 s1 = emit_load_s1(jd, iptr, src, REG_FTMP1);
1557 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP3);
1564 emit_store(jd, iptr, iptr->dst, d);
1567 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1569 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1570 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1571 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1573 M_LSUB_IMM(REG_ZERO, 1, d);
1574 M_FCMPEQ(s1, s2, REG_FTMP3);
1575 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1577 M_FCMPLT(s2, s1, REG_FTMP3);
1578 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1579 M_LADD_IMM(REG_ZERO, 1, d);
1581 M_LSUB_IMM(REG_ZERO, 1, d);
1582 M_FCMPEQS(s1, s2, REG_FTMP3);
1584 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1586 M_FCMPLTS(s2, s1, REG_FTMP3);
1588 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1589 M_LADD_IMM(REG_ZERO, 1, d);
1591 emit_store(jd, iptr, iptr->dst, d);
1594 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1596 s1 = emit_load_s1(jd, iptr, src->prev, REG_FTMP1);
1597 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
1598 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP3);
1600 M_LADD_IMM(REG_ZERO, 1, d);
1601 M_FCMPEQ(s1, s2, REG_FTMP3);
1602 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1604 M_FCMPLT(s1, s2, REG_FTMP3);
1605 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1606 M_LSUB_IMM(REG_ZERO, 1, d);
1608 M_LADD_IMM(REG_ZERO, 1, d);
1609 M_FCMPEQS(s1, s2, REG_FTMP3);
1611 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1613 M_FCMPLTS(s1, s2, REG_FTMP3);
1615 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1616 M_LSUB_IMM(REG_ZERO, 1, d);
1618 emit_store(jd, iptr, iptr->dst, d);
1622 /* memory operations **************************************************/
1624 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1626 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
1627 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1628 gen_nullptr_check(s1);
1629 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1630 emit_store(jd, iptr, iptr->dst, d);
1633 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1635 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1636 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1637 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1638 if (iptr->op1 == 0) {
1639 gen_nullptr_check(s1);
1642 if (has_ext_instr_set) {
1643 M_LADD (s2, s1, REG_ITMP1);
1644 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1647 M_LADD(s2, s1, REG_ITMP1);
1648 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1649 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1650 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1651 M_SRA_IMM(d, 56, d);
1653 emit_store(jd, iptr, iptr->dst, d);
1656 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1658 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1659 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1660 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1661 if (iptr->op1 == 0) {
1662 gen_nullptr_check(s1);
1665 if (has_ext_instr_set) {
1666 M_LADD(s2, s1, REG_ITMP1);
1667 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1668 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1670 M_LADD (s2, s1, REG_ITMP1);
1671 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1672 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1673 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1674 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1676 emit_store(jd, iptr, iptr->dst, d);
1679 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1681 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1682 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1683 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1684 if (iptr->op1 == 0) {
1685 gen_nullptr_check(s1);
1688 if (has_ext_instr_set) {
1689 M_LADD(s2, s1, REG_ITMP1);
1690 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1691 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1694 M_LADD(s2, s1, REG_ITMP1);
1695 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1696 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1697 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1698 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1699 M_SRA_IMM(d, 48, d);
1701 emit_store(jd, iptr, iptr->dst, d);
1704 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1706 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1707 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1708 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1709 if (iptr->op1 == 0) {
1710 gen_nullptr_check(s1);
1713 M_S4ADDQ(s2, s1, REG_ITMP1);
1714 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1715 emit_store(jd, iptr, iptr->dst, d);
1718 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1720 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1721 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1722 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1723 if (iptr->op1 == 0) {
1724 gen_nullptr_check(s1);
1727 M_S8ADDQ(s2, s1, REG_ITMP1);
1728 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1729 emit_store(jd, iptr, iptr->dst, d);
1732 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1734 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1735 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1736 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1737 if (iptr->op1 == 0) {
1738 gen_nullptr_check(s1);
1741 M_S4ADDQ(s2, s1, REG_ITMP1);
1742 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1743 emit_store(jd, iptr, iptr->dst, d);
1746 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1748 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1749 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1750 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP2);
1751 if (iptr->op1 == 0) {
1752 gen_nullptr_check(s1);
1755 M_S8ADDQ(s2, s1, REG_ITMP1);
1756 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1757 emit_store(jd, iptr, iptr->dst, d);
1760 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1762 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1763 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1764 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
1765 if (iptr->op1 == 0) {
1766 gen_nullptr_check(s1);
1769 M_SAADDQ(s2, s1, REG_ITMP1);
1770 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1771 emit_store(jd, iptr, iptr->dst, d);
1775 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1777 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1778 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1779 if (iptr->op1 == 0) {
1780 gen_nullptr_check(s1);
1783 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1784 if (has_ext_instr_set) {
1785 M_LADD(s2, s1, REG_ITMP1);
1786 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1788 M_LADD(s2, s1, REG_ITMP1);
1789 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1790 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1791 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1792 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1793 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1794 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1798 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1800 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1801 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1802 if (iptr->op1 == 0) {
1803 gen_nullptr_check(s1);
1806 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1807 if (has_ext_instr_set) {
1808 M_LADD(s2, s1, REG_ITMP1);
1809 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1810 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1812 M_LADD(s2, s1, REG_ITMP1);
1813 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1814 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1815 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1816 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1817 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1818 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1819 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1823 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1825 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1826 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1827 if (iptr->op1 == 0) {
1828 gen_nullptr_check(s1);
1831 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1832 if (has_ext_instr_set) {
1833 M_LADD(s2, s1, REG_ITMP1);
1834 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1835 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1837 M_LADD(s2, s1, REG_ITMP1);
1838 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1839 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1840 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1841 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1842 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1843 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1844 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1848 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1850 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1851 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1852 if (iptr->op1 == 0) {
1853 gen_nullptr_check(s1);
1856 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1857 M_S4ADDQ(s2, s1, REG_ITMP1);
1858 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1861 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1863 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1864 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1865 if (iptr->op1 == 0) {
1866 gen_nullptr_check(s1);
1869 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1870 M_S8ADDQ(s2, s1, REG_ITMP1);
1871 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1874 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1876 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1877 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1878 if (iptr->op1 == 0) {
1879 gen_nullptr_check(s1);
1882 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1883 M_S4ADDQ(s2, s1, REG_ITMP1);
1884 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1887 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1889 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1890 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1891 if (iptr->op1 == 0) {
1892 gen_nullptr_check(s1);
1895 s3 = emit_load_s3(jd, iptr, src, REG_FTMP3);
1896 M_S8ADDQ(s2, s1, REG_ITMP1);
1897 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1900 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1902 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1903 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1904 if (iptr->op1 == 0) {
1905 gen_nullptr_check(s1);
1908 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1910 M_MOV(s1, rd->argintregs[0]);
1911 M_MOV(s3, rd->argintregs[1]);
1912 disp = dseg_addaddress(cd, BUILTIN_canstore);
1913 M_ALD(REG_PV, REG_PV, disp);
1914 M_JSR(REG_RA, REG_PV);
1915 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
1916 M_LDA(REG_PV, REG_RA, -disp);
1918 M_BEQZ(REG_RESULT, 0);
1919 codegen_add_arraystoreexception_ref(cd);
1921 s1 = emit_load_s1(jd, iptr, src->prev->prev, REG_ITMP1);
1922 s2 = emit_load_s2(jd, iptr, src->prev, REG_ITMP2);
1923 s3 = emit_load_s3(jd, iptr, src, REG_ITMP3);
1924 M_SAADDQ(s2, s1, REG_ITMP1);
1925 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1929 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1931 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1932 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1933 if (iptr->op1 == 0) {
1934 gen_nullptr_check(s1);
1937 M_S4ADDQ(s2, s1, REG_ITMP1);
1938 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1941 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1943 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1944 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1945 if (iptr->op1 == 0) {
1946 gen_nullptr_check(s1);
1949 M_S8ADDQ(s2, s1, REG_ITMP1);
1950 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1953 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1955 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1956 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1957 if (iptr->op1 == 0) {
1958 gen_nullptr_check(s1);
1961 M_SAADDQ(s2, s1, REG_ITMP1);
1962 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1965 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1967 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1968 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1969 if (iptr->op1 == 0) {
1970 gen_nullptr_check(s1);
1973 if (has_ext_instr_set) {
1974 M_LADD(s2, s1, REG_ITMP1);
1975 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1978 M_LADD(s2, s1, REG_ITMP1);
1979 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1980 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1981 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1982 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1983 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1984 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1988 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1990 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
1991 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
1992 if (iptr->op1 == 0) {
1993 gen_nullptr_check(s1);
1996 if (has_ext_instr_set) {
1997 M_LADD(s2, s1, REG_ITMP1);
1998 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1999 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2002 M_LADD(s2, s1, REG_ITMP1);
2003 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2004 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2005 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2006 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2007 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2008 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2009 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2013 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2015 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2016 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2017 if (iptr->op1 == 0) {
2018 gen_nullptr_check(s1);
2021 if (has_ext_instr_set) {
2022 M_LADD(s2, s1, REG_ITMP1);
2023 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2024 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2027 M_LADD(s2, s1, REG_ITMP1);
2028 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2029 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2030 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2031 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2032 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2033 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2034 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2039 case ICMD_GETSTATIC: /* ... ==> ..., value */
2040 /* op1 = type, val.a = field address */
2042 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2043 disp = dseg_addaddress(cd, 0);
2045 codegen_addpatchref(cd, PATCHER_get_putstatic,
2046 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2048 if (opt_showdisassemble)
2053 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2055 disp = dseg_addaddress(cd, &(fi->value));
2057 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2058 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2060 if (opt_showdisassemble)
2065 M_ALD(REG_ITMP1, REG_PV, disp);
2066 switch (iptr->op1) {
2068 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2069 M_ILD(d, REG_ITMP1, 0);
2072 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2073 M_LLD(d, REG_ITMP1, 0);
2076 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2077 M_ALD(d, REG_ITMP1, 0);
2080 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2081 M_FLD(d, REG_ITMP1, 0);
2084 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2085 M_DLD(d, REG_ITMP1, 0);
2088 emit_store(jd, iptr, iptr->dst, d);
2091 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2092 /* op1 = type, val.a = field address */
2094 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2095 disp = dseg_addaddress(cd, 0);
2097 codegen_addpatchref(cd, PATCHER_get_putstatic,
2098 INSTRUCTION_UNRESOLVED_FIELD(iptr), disp);
2100 if (opt_showdisassemble)
2104 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr);
2106 disp = dseg_addaddress(cd, &(fi->value));
2108 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2109 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2111 if (opt_showdisassemble)
2116 M_ALD(REG_ITMP1, REG_PV, disp);
2117 switch (iptr->op1) {
2119 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2120 M_IST(s2, REG_ITMP1, 0);
2123 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2124 M_LST(s2, REG_ITMP1, 0);
2127 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2128 M_AST(s2, REG_ITMP1, 0);
2131 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2132 M_FST(s2, REG_ITMP1, 0);
2135 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2136 M_DST(s2, REG_ITMP1, 0);
2141 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2142 /* val = value (in current instruction) */
2143 /* op1 = type, val.a = field address (in */
2144 /* following NOP) */
2146 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2147 disp = dseg_addaddress(cd, 0);
2149 codegen_addpatchref(cd, PATCHER_get_putstatic,
2150 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), disp);
2152 if (opt_showdisassemble)
2156 fieldinfo *fi = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1);
2158 disp = dseg_addaddress(cd, &(fi->value));
2160 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2161 codegen_addpatchref(cd, PATCHER_clinit, fi->class, 0);
2163 if (opt_showdisassemble)
2168 M_ALD(REG_ITMP1, REG_PV, disp);
2169 switch (iptr->op1) {
2171 M_IST(REG_ZERO, REG_ITMP1, 0);
2174 M_LST(REG_ZERO, REG_ITMP1, 0);
2177 M_AST(REG_ZERO, REG_ITMP1, 0);
2180 M_FST(REG_ZERO, REG_ITMP1, 0);
2183 M_DST(REG_ZERO, REG_ITMP1, 0);
2189 case ICMD_GETFIELD: /* ... ==> ..., value */
2190 /* op1 = type, val.i = field offset */
2192 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2193 gen_nullptr_check(s1);
2195 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2196 codegen_addpatchref(cd, PATCHER_get_putfield,
2197 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2199 if (opt_showdisassemble)
2205 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2208 switch (iptr->op1) {
2210 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2214 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2218 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2222 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2226 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FTMP1);
2230 emit_store(jd, iptr, iptr->dst, d);
2233 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2234 /* op1 = type, val.a = field address */
2236 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2237 gen_nullptr_check(s1);
2239 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2240 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2242 s2 = emit_load_s2(jd, iptr, src, REG_FTMP2);
2245 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
2246 codegen_addpatchref(cd, PATCHER_get_putfield,
2247 INSTRUCTION_UNRESOLVED_FIELD(iptr), 0);
2249 if (opt_showdisassemble)
2255 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr)->offset;
2258 switch (iptr->op1) {
2260 M_IST(s2, s1, disp);
2263 M_LST(s2, s1, disp);
2266 M_AST(s2, s1, disp);
2269 M_FST(s2, s1, disp);
2272 M_DST(s2, s1, disp);
2277 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2278 /* val = value (in current instruction) */
2279 /* op1 = type, val.a = field address (in */
2280 /* following NOP) */
2282 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2283 gen_nullptr_check(s1);
2285 if (INSTRUCTION_IS_UNRESOLVED(iptr + 1)) {
2286 codegen_addpatchref(cd, PATCHER_get_putfield,
2287 INSTRUCTION_UNRESOLVED_FIELD(iptr + 1), 0);
2289 if (opt_showdisassemble)
2295 disp = INSTRUCTION_RESOLVED_FIELDINFO(iptr + 1)->offset;
2298 switch (iptr[1].op1) {
2300 M_IST(REG_ZERO, s1, disp);
2303 M_LST(REG_ZERO, s1, disp);
2306 M_AST(REG_ZERO, s1, disp);
2309 M_FST(REG_ZERO, s1, disp);
2312 M_DST(REG_ZERO, s1, disp);
2318 /* branch operations **************************************************/
2320 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2322 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2323 M_INTMOVE(s1, REG_ITMP1_XPTR);
2325 #ifdef ENABLE_VERIFIER
2327 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2328 (unresolved_class *) iptr->val.a, 0);
2330 if (opt_showdisassemble)
2333 #endif /* ENABLE_VERIFIER */
2335 disp = dseg_addaddress(cd, asm_handle_exception);
2336 M_ALD(REG_ITMP2, REG_PV, disp);
2337 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2338 M_NOP; /* nop ensures that XPC is less than the end */
2339 /* of basic block */
2343 case ICMD_GOTO: /* ... ==> ... */
2344 /* op1 = target JavaVM pc */
2346 codegen_addreference(cd, (basicblock *) iptr->target);
2350 case ICMD_JSR: /* ... ==> ... */
2351 /* op1 = target JavaVM pc */
2353 M_BSR(REG_ITMP1, 0);
2354 codegen_addreference(cd, (basicblock *) iptr->target);
2357 case ICMD_RET: /* ... ==> ... */
2358 /* op1 = local variable */
2360 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2361 if (var->flags & INMEMORY) {
2362 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2363 M_RET(REG_ZERO, REG_ITMP1);
2366 M_RET(REG_ZERO, var->regoff);
2370 case ICMD_IFNULL: /* ..., value ==> ... */
2371 /* op1 = target JavaVM pc */
2373 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2375 codegen_addreference(cd, (basicblock *) iptr->target);
2378 case ICMD_IFNONNULL: /* ..., value ==> ... */
2379 /* op1 = target JavaVM pc */
2381 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2383 codegen_addreference(cd, (basicblock *) iptr->target);
2386 case ICMD_IFEQ: /* ..., value ==> ... */
2387 /* op1 = target JavaVM pc, val.i = constant */
2389 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2390 if (iptr->val.i == 0) {
2394 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2395 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2398 ICONST(REG_ITMP2, iptr->val.i);
2399 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2401 M_BNEZ(REG_ITMP1, 0);
2403 codegen_addreference(cd, (basicblock *) iptr->target);
2406 case ICMD_IFLT: /* ..., value ==> ... */
2407 /* op1 = target JavaVM pc, val.i = constant */
2409 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2410 if (iptr->val.i == 0) {
2414 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2415 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2418 ICONST(REG_ITMP2, iptr->val.i);
2419 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2421 M_BNEZ(REG_ITMP1, 0);
2423 codegen_addreference(cd, (basicblock *) iptr->target);
2426 case ICMD_IFLE: /* ..., value ==> ... */
2427 /* op1 = target JavaVM pc, val.i = constant */
2429 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2430 if (iptr->val.i == 0) {
2434 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2435 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2438 ICONST(REG_ITMP2, iptr->val.i);
2439 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2441 M_BNEZ(REG_ITMP1, 0);
2443 codegen_addreference(cd, (basicblock *) iptr->target);
2446 case ICMD_IFNE: /* ..., value ==> ... */
2447 /* op1 = target JavaVM pc, val.i = constant */
2449 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2450 if (iptr->val.i == 0) {
2454 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2455 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2458 ICONST(REG_ITMP2, iptr->val.i);
2459 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2461 M_BEQZ(REG_ITMP1, 0);
2463 codegen_addreference(cd, (basicblock *) iptr->target);
2466 case ICMD_IFGT: /* ..., value ==> ... */
2467 /* op1 = target JavaVM pc, val.i = constant */
2469 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2470 if (iptr->val.i == 0) {
2474 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2475 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2478 ICONST(REG_ITMP2, iptr->val.i);
2479 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2481 M_BEQZ(REG_ITMP1, 0);
2483 codegen_addreference(cd, (basicblock *) iptr->target);
2486 case ICMD_IFGE: /* ..., value ==> ... */
2487 /* op1 = target JavaVM pc, val.i = constant */
2489 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2490 if (iptr->val.i == 0) {
2494 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2495 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2498 ICONST(REG_ITMP2, iptr->val.i);
2499 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2501 M_BEQZ(REG_ITMP1, 0);
2503 codegen_addreference(cd, (basicblock *) iptr->target);
2506 case ICMD_IF_LEQ: /* ..., value ==> ... */
2507 /* op1 = target JavaVM pc, val.l = constant */
2509 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2510 if (iptr->val.l == 0) {
2514 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2515 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2518 LCONST(REG_ITMP2, iptr->val.l);
2519 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2521 M_BNEZ(REG_ITMP1, 0);
2523 codegen_addreference(cd, (basicblock *) iptr->target);
2526 case ICMD_IF_LLT: /* ..., value ==> ... */
2527 /* op1 = target JavaVM pc, val.l = constant */
2529 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2530 if (iptr->val.l == 0) {
2534 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2535 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2538 LCONST(REG_ITMP2, iptr->val.l);
2539 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2541 M_BNEZ(REG_ITMP1, 0);
2543 codegen_addreference(cd, (basicblock *) iptr->target);
2546 case ICMD_IF_LLE: /* ..., value ==> ... */
2547 /* op1 = target JavaVM pc, val.l = constant */
2549 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2550 if (iptr->val.l == 0) {
2554 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2555 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2558 LCONST(REG_ITMP2, iptr->val.l);
2559 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2561 M_BNEZ(REG_ITMP1, 0);
2563 codegen_addreference(cd, (basicblock *) iptr->target);
2566 case ICMD_IF_LNE: /* ..., value ==> ... */
2567 /* op1 = target JavaVM pc, val.l = constant */
2569 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2570 if (iptr->val.l == 0) {
2574 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2575 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2578 LCONST(REG_ITMP2, iptr->val.l);
2579 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2581 M_BEQZ(REG_ITMP1, 0);
2583 codegen_addreference(cd, (basicblock *) iptr->target);
2586 case ICMD_IF_LGT: /* ..., value ==> ... */
2587 /* op1 = target JavaVM pc, val.l = constant */
2589 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2590 if (iptr->val.l == 0) {
2594 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2595 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2598 LCONST(REG_ITMP2, iptr->val.l);
2599 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2601 M_BEQZ(REG_ITMP1, 0);
2603 codegen_addreference(cd, (basicblock *) iptr->target);
2606 case ICMD_IF_LGE: /* ..., value ==> ... */
2607 /* op1 = target JavaVM pc, val.l = constant */
2609 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2610 if (iptr->val.l == 0) {
2614 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2615 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2618 LCONST(REG_ITMP2, iptr->val.l);
2619 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2621 M_BEQZ(REG_ITMP1, 0);
2623 codegen_addreference(cd, (basicblock *) iptr->target);
2626 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2627 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2628 case ICMD_IF_ACMPEQ:
2630 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2631 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2632 M_CMPEQ(s1, s2, REG_ITMP1);
2633 M_BNEZ(REG_ITMP1, 0);
2634 codegen_addreference(cd, (basicblock *) iptr->target);
2637 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2638 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2639 case ICMD_IF_ACMPNE:
2641 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2642 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2643 M_CMPEQ(s1, s2, REG_ITMP1);
2644 M_BEQZ(REG_ITMP1, 0);
2645 codegen_addreference(cd, (basicblock *) iptr->target);
2648 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2649 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2651 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2652 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2653 M_CMPLT(s1, s2, REG_ITMP1);
2654 M_BNEZ(REG_ITMP1, 0);
2655 codegen_addreference(cd, (basicblock *) iptr->target);
2658 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2659 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2661 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2662 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2663 M_CMPLE(s1, s2, REG_ITMP1);
2664 M_BEQZ(REG_ITMP1, 0);
2665 codegen_addreference(cd, (basicblock *) iptr->target);
2668 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2669 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2671 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2672 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2673 M_CMPLE(s1, s2, REG_ITMP1);
2674 M_BNEZ(REG_ITMP1, 0);
2675 codegen_addreference(cd, (basicblock *) iptr->target);
2678 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2679 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2681 s1 = emit_load_s1(jd, iptr, src->prev, REG_ITMP1);
2682 s2 = emit_load_s2(jd, iptr, src, REG_ITMP2);
2683 M_CMPLT(s1, s2, REG_ITMP1);
2684 M_BEQZ(REG_ITMP1, 0);
2685 codegen_addreference(cd, (basicblock *) iptr->target);
2688 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2690 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2693 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2694 /* val.i = constant */
2696 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2697 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2699 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2700 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2701 M_CMPEQ(s1, REG_ZERO, d);
2702 emit_store(jd, iptr, iptr->dst, d);
2705 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2706 M_CMPEQ(s1, REG_ZERO, d);
2708 emit_store(jd, iptr, iptr->dst, d);
2712 M_MOV(s1, REG_ITMP1);
2715 ICONST(d, iptr[1].val.i);
2717 if ((s3 >= 0) && (s3 <= 255)) {
2718 M_CMOVEQ_IMM(s1, s3, d);
2720 ICONST(REG_ITMP3, s3);
2721 M_CMOVEQ(s1, REG_ITMP3, d);
2723 emit_store(jd, iptr, iptr->dst, d);
2726 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2727 /* val.i = constant */
2729 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2730 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2732 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2733 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2734 M_CMPEQ(s1, REG_ZERO, d);
2735 emit_store(jd, iptr, iptr->dst, d);
2738 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2739 M_CMPEQ(s1, REG_ZERO, d);
2741 emit_store(jd, iptr, iptr->dst, d);
2745 M_MOV(s1, REG_ITMP1);
2748 ICONST(d, iptr[1].val.i);
2750 if ((s3 >= 0) && (s3 <= 255)) {
2751 M_CMOVNE_IMM(s1, s3, d);
2753 ICONST(REG_ITMP3, s3);
2754 M_CMOVNE(s1, REG_ITMP3, d);
2756 emit_store(jd, iptr, iptr->dst, d);
2759 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2760 /* val.i = constant */
2762 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2763 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2765 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2766 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2767 M_CMPLT(s1, REG_ZERO, d);
2768 emit_store(jd, iptr, iptr->dst, d);
2771 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2772 M_CMPLE(REG_ZERO, s1, d);
2773 emit_store(jd, iptr, iptr->dst, d);
2777 M_MOV(s1, REG_ITMP1);
2780 ICONST(d, iptr[1].val.i);
2782 if ((s3 >= 0) && (s3 <= 255)) {
2783 M_CMOVLT_IMM(s1, s3, d);
2785 ICONST(REG_ITMP3, s3);
2786 M_CMOVLT(s1, REG_ITMP3, d);
2788 emit_store(jd, iptr, iptr->dst, d);
2791 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2792 /* val.i = constant */
2794 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2795 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2797 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2798 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2799 M_CMPLE(REG_ZERO, s1, d);
2800 emit_store(jd, iptr, iptr->dst, d);
2803 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2804 M_CMPLT(s1, REG_ZERO, d);
2805 emit_store(jd, iptr, iptr->dst, d);
2809 M_MOV(s1, REG_ITMP1);
2812 ICONST(d, iptr[1].val.i);
2814 if ((s3 >= 0) && (s3 <= 255)) {
2815 M_CMOVGE_IMM(s1, s3, d);
2817 ICONST(REG_ITMP3, s3);
2818 M_CMOVGE(s1, REG_ITMP3, d);
2820 emit_store(jd, iptr, iptr->dst, d);
2823 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2824 /* val.i = constant */
2826 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2827 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2829 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2830 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2831 M_CMPLT(REG_ZERO, s1, d);
2832 emit_store(jd, iptr, iptr->dst, d);
2835 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2836 M_CMPLE(s1, REG_ZERO, d);
2837 emit_store(jd, iptr, iptr->dst, d);
2841 M_MOV(s1, REG_ITMP1);
2844 ICONST(d, iptr[1].val.i);
2846 if ((s3 >= 0) && (s3 <= 255)) {
2847 M_CMOVGT_IMM(s1, s3, d);
2849 ICONST(REG_ITMP3, s3);
2850 M_CMOVGT(s1, REG_ITMP3, d);
2852 emit_store(jd, iptr, iptr->dst, d);
2855 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2856 /* val.i = constant */
2858 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
2859 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
2861 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2862 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2863 M_CMPLE(s1, REG_ZERO, d);
2864 emit_store(jd, iptr, iptr->dst, d);
2867 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2868 M_CMPLT(REG_ZERO, s1, d);
2869 emit_store(jd, iptr, iptr->dst, d);
2873 M_MOV(s1, REG_ITMP1);
2876 ICONST(d, iptr[1].val.i);
2878 if ((s3 >= 0) && (s3 <= 255)) {
2879 M_CMOVLE_IMM(s1, s3, d);
2881 ICONST(REG_ITMP3, s3);
2882 M_CMOVLE(s1, REG_ITMP3, d);
2884 emit_store(jd, iptr, iptr->dst, d);
2888 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2891 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2892 M_INTMOVE(s1, REG_RESULT);
2893 goto nowperformreturn;
2895 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2897 s1 = emit_load_s1(jd, iptr, src, REG_RESULT);
2898 M_INTMOVE(s1, REG_RESULT);
2900 #ifdef ENABLE_VERIFIER
2902 codegen_addpatchref(cd, PATCHER_athrow_areturn,
2903 (unresolved_class *) iptr->val.a, 0);
2905 if (opt_showdisassemble)
2908 #endif /* ENABLE_VERIFIER */
2909 goto nowperformreturn;
2911 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2914 s1 = emit_load_s1(jd, iptr, src, REG_FRESULT);
2915 M_FLTMOVE(s1, REG_FRESULT);
2916 goto nowperformreturn;
2918 case ICMD_RETURN: /* ... ==> ... */
2926 /* call trace function */
2928 #if !defined(NDEBUG)
2929 if (opt_verbosecall) {
2930 M_LDA(REG_SP, REG_SP, -3 * 8);
2931 M_AST(REG_RA, REG_SP, 0 * 8);
2932 M_LST(REG_RESULT, REG_SP, 1 * 8);
2933 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2935 disp = dseg_addaddress(cd, m);
2936 M_ALD(rd->argintregs[0], REG_PV, disp);
2937 M_MOV(REG_RESULT, rd->argintregs[1]);
2938 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2939 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2941 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2942 M_ALD(REG_PV, REG_PV, disp);
2943 M_JSR(REG_RA, REG_PV);
2944 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
2945 M_LDA(REG_PV, REG_RA, -disp);
2947 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2948 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2949 M_ALD(REG_RA, REG_SP, 0 * 8);
2950 M_LDA(REG_SP, REG_SP, 3 * 8);
2954 #if defined(USE_THREADS)
2955 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2956 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2958 switch (iptr->opc) {
2962 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2966 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2970 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2971 M_ALD(REG_PV, REG_PV, disp);
2972 M_JSR(REG_RA, REG_PV);
2973 disp = -(s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
2974 M_LDA(REG_PV, REG_RA, disp);
2976 switch (iptr->opc) {
2980 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2984 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2990 /* restore return address */
2992 if (!m->isleafmethod) {
2993 p--; M_LLD(REG_RA, REG_SP, p * 8);
2996 /* restore saved registers */
2998 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2999 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
3001 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3002 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3005 /* deallocate stack */
3008 M_LDA(REG_SP, REG_SP, stackframesize * 8);
3010 M_RET(REG_ZERO, REG_RA);
3016 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3021 tptr = (void **) iptr->target;
3023 s4ptr = iptr->val.a;
3024 l = s4ptr[1]; /* low */
3025 i = s4ptr[2]; /* high */
3027 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3029 M_INTMOVE(s1, REG_ITMP1);
3030 } else if (l <= 32768) {
3031 M_LDA(REG_ITMP1, s1, -l);
3033 ICONST(REG_ITMP2, l);
3034 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3041 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3043 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3044 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3046 M_BEQZ(REG_ITMP2, 0);
3047 codegen_addreference(cd, (basicblock *) tptr[0]);
3049 /* build jump table top down and use address of lowest entry */
3051 /* s4ptr += 3 + i; */
3055 dseg_addtarget(cd, (basicblock *) tptr[0]);
3060 /* length of dataseg after last dseg_addtarget is used by load */
3062 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3063 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3064 M_JMP(REG_ZERO, REG_ITMP2);
3069 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3071 s4 i, l, val, *s4ptr;
3074 tptr = (void **) iptr->target;
3076 s4ptr = iptr->val.a;
3077 l = s4ptr[0]; /* default */
3078 i = s4ptr[1]; /* count */
3080 MCODECHECK((i<<2)+8);
3081 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3087 if ((val >= 0) && (val <= 255)) {
3088 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3090 if ((val >= -32768) && (val <= 32767)) {
3091 M_LDA(REG_ITMP2, REG_ZERO, val);
3093 disp = dseg_adds4(cd, val);
3094 M_ILD(REG_ITMP2, REG_PV, disp);
3096 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3098 M_BNEZ(REG_ITMP2, 0);
3099 codegen_addreference(cd, (basicblock *) tptr[0]);
3104 tptr = (void **) iptr->target;
3105 codegen_addreference(cd, (basicblock *) tptr[0]);
3112 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3113 /* op1 = arg count val.a = builtintable entry */
3119 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3120 /* op1 = arg count, val.a = method pointer */
3122 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3123 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3124 case ICMD_INVOKEINTERFACE:
3126 if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
3127 md = INSTRUCTION_UNRESOLVED_METHOD(iptr)->methodref->parseddesc.md;
3131 lm = INSTRUCTION_RESOLVED_METHODINFO(iptr);
3132 md = lm->parseddesc;
3136 s3 = md->paramcount;
3138 MCODECHECK((s3 << 1) + 64);
3140 /* copy arguments to registers or stack location */
3142 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3143 if (src->varkind == ARGVAR)
3145 if (IS_INT_LNG_TYPE(src->type)) {
3146 if (!md->params[s3].inmemory) {
3147 s1 = rd->argintregs[md->params[s3].regoff];
3148 d = emit_load_s1(jd, iptr, src, s1);
3151 d = emit_load_s1(jd, iptr, src, REG_ITMP1);
3152 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3156 if (!md->params[s3].inmemory) {
3157 s1 = rd->argfltregs[md->params[s3].regoff];
3158 d = emit_load_s1(jd, iptr, src, s1);
3161 d = emit_load_s1(jd, iptr, src, REG_FTMP1);
3162 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3167 switch (iptr->opc) {
3169 disp = dseg_addaddress(cd, bte->fp);
3170 d = md->returntype.type;
3172 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3173 M_JSR(REG_RA, REG_PV);
3174 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3175 M_LDA(REG_PV, REG_RA, -disp);
3177 /* if op1 == true, we need to check for an exception */
3179 if (iptr->op1 == true) {
3180 M_BEQZ(REG_RESULT, 0);
3181 codegen_add_fillinstacktrace_ref(cd);
3185 case ICMD_INVOKESPECIAL:
3186 M_BEQZ(rd->argintregs[0], 0);
3187 codegen_add_nullpointerexception_ref(cd);
3190 case ICMD_INVOKESTATIC:
3192 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3194 disp = dseg_addaddress(cd, NULL);
3196 codegen_addpatchref(cd, PATCHER_invokestatic_special,
3199 if (opt_showdisassemble)
3202 d = um->methodref->parseddesc.md->returntype.type;
3205 disp = dseg_addaddress(cd, lm->stubroutine);
3206 d = lm->parseddesc->returntype.type;
3209 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3210 M_JSR(REG_RA, REG_PV);
3211 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3212 M_LDA(REG_PV, REG_RA, -disp);
3215 case ICMD_INVOKEVIRTUAL:
3216 gen_nullptr_check(rd->argintregs[0]);
3219 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3221 codegen_addpatchref(cd, PATCHER_invokevirtual, um, 0);
3223 if (opt_showdisassemble)
3227 d = um->methodref->parseddesc.md->returntype.type;
3230 s1 = OFFSET(vftbl_t, table[0]) +
3231 sizeof(methodptr) * lm->vftblindex;
3232 d = lm->parseddesc->returntype.type;
3235 M_ALD(REG_METHODPTR, rd->argintregs[0],
3236 OFFSET(java_objectheader, vftbl));
3237 M_ALD(REG_PV, REG_METHODPTR, s1);
3238 M_JSR(REG_RA, REG_PV);
3239 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3240 M_LDA(REG_PV, REG_RA, -disp);
3243 case ICMD_INVOKEINTERFACE:
3244 gen_nullptr_check(rd->argintregs[0]);
3247 unresolved_method *um = INSTRUCTION_UNRESOLVED_METHOD(iptr);
3249 codegen_addpatchref(cd, PATCHER_invokeinterface, um, 0);
3251 if (opt_showdisassemble)
3256 d = um->methodref->parseddesc.md->returntype.type;
3259 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3260 sizeof(methodptr*) * lm->class->index;
3262 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3264 d = lm->parseddesc->returntype.type;
3267 M_ALD(REG_METHODPTR, rd->argintregs[0],
3268 OFFSET(java_objectheader, vftbl));
3269 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3270 M_ALD(REG_PV, REG_METHODPTR, s2);
3271 M_JSR(REG_RA, REG_PV);
3272 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3273 M_LDA(REG_PV, REG_RA, -disp);
3277 /* d contains return type */
3279 if (d != TYPE_VOID) {
3280 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3281 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3282 M_INTMOVE(REG_RESULT, s1);
3283 /* emit_store(jd, iptr, iptr->dst, s1); */
3285 s1 = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_FRESULT);
3286 M_FLTMOVE(REG_FRESULT, s1);
3287 /* emit_store(jd, iptr, iptr->dst, s1); */
3289 emit_store(jd, iptr, iptr->dst, s1);
3294 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3296 /* op1: 0 == array, 1 == class */
3297 /* val.a: (classinfo*) superclass */
3299 /* superclass is an interface:
3301 * OK if ((sub == NULL) ||
3302 * (sub->vftbl->interfacetablelength > super->index) &&
3303 * (sub->vftbl->interfacetable[-super->index] != NULL));
3305 * superclass is a class:
3307 * OK if ((sub == NULL) || (0
3308 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3309 * super->vftbl->diffval));
3312 if (iptr->op1 == 1) {
3313 /* object type cast-check */
3316 vftbl_t *supervftbl;
3319 super = (classinfo *) iptr->val.a;
3326 superindex = super->index;
3327 supervftbl = super->vftbl;
3330 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3331 codegen_threadcritrestart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3333 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3335 /* calculate interface checkcast code size */
3339 s2 += opt_showdisassemble ? 1 : 0;
3341 /* calculate class checkcast code size */
3343 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3345 s3 += opt_showdisassemble ? 1 : 0;
3347 /* if class is not resolved, check which code to call */
3350 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3352 disp = dseg_adds4(cd, 0); /* super->flags */
3354 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3355 (constant_classref *) iptr->target,
3358 if (opt_showdisassemble)
3361 M_ILD(REG_ITMP2, REG_PV, disp);
3362 disp = dseg_adds4(cd, ACC_INTERFACE);
3363 M_ILD(REG_ITMP3, REG_PV, disp);
3364 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3365 M_BEQZ(REG_ITMP2, s2 + 1);
3368 /* interface checkcast code */
3370 if (!super || (super->flags & ACC_INTERFACE)) {
3375 codegen_addpatchref(cd,
3376 PATCHER_checkcast_instanceof_interface,
3377 (constant_classref *) iptr->target,
3380 if (opt_showdisassemble)
3384 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3385 M_ILD(REG_ITMP3, REG_ITMP2,
3386 OFFSET(vftbl_t, interfacetablelength));
3387 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3388 M_BLEZ(REG_ITMP3, 0);
3389 codegen_add_classcastexception_ref(cd);
3390 M_ALD(REG_ITMP3, REG_ITMP2,
3391 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3392 superindex * sizeof(methodptr*)));
3393 M_BEQZ(REG_ITMP3, 0);
3394 codegen_add_classcastexception_ref(cd);
3400 /* class checkcast code */
3402 if (!super || !(super->flags & ACC_INTERFACE)) {
3403 disp = dseg_addaddress(cd, supervftbl);
3409 codegen_addpatchref(cd,
3410 PATCHER_checkcast_instanceof_class,
3411 (constant_classref *) iptr->target,
3414 if (opt_showdisassemble)
3418 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3419 M_ALD(REG_ITMP3, REG_PV, disp);
3420 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3421 codegen_threadcritstart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3423 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3424 /* if (s1 != REG_ITMP1) { */
3425 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3426 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3427 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3428 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3430 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3433 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3434 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3435 M_ALD(REG_ITMP3, REG_PV, disp);
3436 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3437 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3438 codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3441 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3442 M_BEQZ(REG_ITMP3, 0);
3443 codegen_add_classcastexception_ref(cd);
3445 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3448 /* array type cast-check */
3450 s1 = emit_load_s1(jd, iptr, src, rd->argintregs[0]);
3451 M_INTMOVE(s1, rd->argintregs[0]);
3453 disp = dseg_addaddress(cd, iptr->val.a);
3455 if (iptr->val.a == NULL) {
3456 codegen_addpatchref(cd, PATCHER_builtin_arraycheckcast,
3457 (constant_classref *) iptr->target,
3460 if (opt_showdisassemble)
3464 M_ALD(rd->argintregs[1], REG_PV, disp);
3465 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3466 M_ALD(REG_PV, REG_PV, disp);
3467 M_JSR(REG_RA, REG_PV);
3468 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3469 M_LDA(REG_PV, REG_RA, -disp);
3471 M_BEQZ(REG_RESULT, 0);
3472 codegen_add_classcastexception_ref(cd);
3474 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3475 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, s1);
3478 emit_store(jd, iptr, iptr->dst, d);
3481 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3483 /* op1: 0 == array, 1 == class */
3484 /* val.a: (classinfo*) superclass */
3486 /* superclass is an interface:
3488 * return (sub != NULL) &&
3489 * (sub->vftbl->interfacetablelength > super->index) &&
3490 * (sub->vftbl->interfacetable[-super->index] != NULL);
3492 * superclass is a class:
3494 * return ((sub != NULL) && (0
3495 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3496 * super->vftbl->diffvall));
3501 vftbl_t *supervftbl;
3504 super = (classinfo *) iptr->val.a;
3511 superindex = super->index;
3512 supervftbl = super->vftbl;
3515 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3516 codegen_threadcritrestart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3518 s1 = emit_load_s1(jd, iptr, src, REG_ITMP1);
3519 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_ITMP2);
3521 M_MOV(s1, REG_ITMP1);
3525 /* calculate interface instanceof code size */
3529 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3531 /* calculate class instanceof code size */
3535 s3 += (opt_showdisassemble ? 1 : 0);
3537 /* if class is not resolved, check which code to call */
3541 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3543 disp = dseg_adds4(cd, 0); /* super->flags */
3545 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_flags,
3546 (constant_classref *) iptr->target, disp);
3548 if (opt_showdisassemble)
3551 M_ILD(REG_ITMP3, REG_PV, disp);
3553 disp = dseg_adds4(cd, ACC_INTERFACE);
3554 M_ILD(REG_ITMP2, REG_PV, disp);
3555 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3556 M_BEQZ(REG_ITMP3, s2 + 1);
3559 /* interface instanceof code */
3561 if (!super || (super->flags & ACC_INTERFACE)) {
3567 /* If d == REG_ITMP2, then it's destroyed in check code */
3572 codegen_addpatchref(cd,
3573 PATCHER_checkcast_instanceof_interface,
3574 (constant_classref *) iptr->target, 0);
3576 if (opt_showdisassemble)
3580 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3581 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3582 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3583 M_BLEZ(REG_ITMP3, 2);
3584 M_ALD(REG_ITMP1, REG_ITMP1,
3585 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3586 superindex * sizeof(methodptr*)));
3587 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3593 /* class instanceof code */
3595 if (!super || !(super->flags & ACC_INTERFACE)) {
3596 disp = dseg_addaddress(cd, supervftbl);
3603 codegen_addpatchref(cd, PATCHER_checkcast_instanceof_class,
3604 (constant_classref *) iptr->target,
3607 if (opt_showdisassemble)
3611 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3612 M_ALD(REG_ITMP2, REG_PV, disp);
3613 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3614 codegen_threadcritstart(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3616 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3617 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3618 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3619 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3620 codegen_threadcritstop(cd, (u1 *) cd->mcodeptr - cd->mcodebase);
3622 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3623 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3625 emit_store(jd, iptr, iptr->dst, d);
3629 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3630 /* op1 = dimension, val.a = class */
3632 /* check for negative sizes and copy sizes to stack if necessary */
3634 MCODECHECK((iptr->op1 << 1) + 64);
3636 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3637 /* copy SAVEDVAR sizes to stack */
3639 if (src->varkind != ARGVAR) {
3640 s2 = emit_load_s2(jd, iptr, src, REG_ITMP1);
3641 M_LST(s2, REG_SP, s1 * 8);
3645 /* a0 = dimension count */
3647 ICONST(rd->argintregs[0], iptr->op1);
3649 /* is patcher function set? */
3651 if (iptr->val.a == NULL) {
3652 disp = dseg_addaddress(cd, 0);
3654 codegen_addpatchref(cd, PATCHER_builtin_multianewarray,
3655 (constant_classref *) iptr->target,
3658 if (opt_showdisassemble)
3662 disp = dseg_addaddress(cd, iptr->val.a);
3665 /* a1 = arraydescriptor */
3667 M_ALD(rd->argintregs[1], REG_PV, disp);
3669 /* a2 = pointer to dimensions = stack pointer */
3671 M_INTMOVE(REG_SP, rd->argintregs[2]);
3673 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3674 M_ALD(REG_PV, REG_PV, disp);
3675 M_JSR(REG_RA, REG_PV);
3676 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3677 M_LDA(REG_PV, REG_RA, -disp);
3679 /* check for exception before result assignment */
3681 M_BEQZ(REG_RESULT, 0);
3682 codegen_add_fillinstacktrace_ref(cd);
3684 d = codegen_reg_of_var(rd, iptr->opc, iptr->dst, REG_RESULT);
3685 M_INTMOVE(REG_RESULT, d);
3686 emit_store(jd, iptr, iptr->dst, d);
3691 new_internalerror("Unknown ICMD %d", iptr->opc);
3695 } /* for instruction */
3697 /* copy values to interface registers */
3699 src = bptr->outstack;
3700 len = bptr->outdepth;
3702 #if defined(ENABLE_LSRA)
3707 if ((src->varkind != STACKVAR)) {
3709 if (IS_FLT_DBL_TYPE(s2)) {
3710 /* XXX can be one call */
3711 s1 = emit_load_s1(jd, NULL, src, REG_FTMP1);
3712 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3713 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3716 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3720 /* XXX can be one call */
3721 s1 = emit_load_s1(jd, NULL, src, REG_ITMP1);
3722 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3723 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3726 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3732 } /* if (bptr -> flags >= BBREACHED) */
3733 } /* for basic block */
3735 dseg_createlinenumbertable(cd);
3738 /* generate exception and patcher stubs */
3747 savedmcodeptr = NULL;
3749 /* generate exception stubs */
3751 for (eref = cd->exceptionrefs; eref != NULL; eref = eref->next) {
3752 gen_resolvebranch((u1 *) cd->mcodebase + eref->branchpos,
3754 (u1 *) cd->mcodeptr - cd->mcodebase);
3758 /* move index register into REG_ITMP1 */
3760 /* Check if the exception is an
3761 ArrayIndexOutOfBoundsException. If so, move index register
3764 if (eref->reg != -1)
3765 M_MOV(eref->reg, rd->argintregs[4]);
3767 /* calcuate exception address */
3769 M_LDA(rd->argintregs[3], REG_PV, eref->branchpos - 4);
3771 /* move function to call into REG_ITMP3 */
3773 disp = dseg_addaddress(cd, eref->function);
3774 M_ALD(REG_ITMP3, REG_PV, disp);
3776 if (savedmcodeptr != NULL) {
3777 disp = savedmcodeptr - (cd->mcodeptr + 1);
3781 savedmcodeptr = cd->mcodeptr;
3783 M_MOV(REG_PV, rd->argintregs[0]);
3784 M_MOV(REG_SP, rd->argintregs[1]);
3786 if (m->isleafmethod)
3787 M_MOV(REG_RA, rd->argintregs[2]);
3789 M_ALD(rd->argintregs[2],
3790 REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
3792 M_LDA(REG_SP, REG_SP, -2 * 8);
3793 M_AST(rd->argintregs[3], REG_SP, 0 * 8); /* store XPC */
3795 if (m->isleafmethod)
3796 M_AST(REG_RA, REG_SP, 1 * 8);
3798 M_MOV(REG_ITMP3, REG_PV);
3799 M_JSR(REG_RA, REG_PV);
3800 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
3801 M_LDA(REG_PV, REG_RA, -disp);
3803 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3805 if (m->isleafmethod)
3806 M_ALD(REG_RA, REG_SP, 1 * 8);
3808 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3809 M_LDA(REG_SP, REG_SP, 2 * 8);
3811 disp = dseg_addaddress(cd, asm_handle_exception);
3812 M_ALD(REG_ITMP3, REG_PV, disp);
3813 M_JMP(REG_ZERO, REG_ITMP3);
3818 /* generate code patching stub call code */
3820 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
3821 /* check code segment size */
3825 /* Get machine code which is patched back in later. The
3826 call is 1 instruction word long. */
3828 savedmcodeptr = (u4 *) (cd->mcodebase + pref->branchpos);
3829 mcode = *savedmcodeptr;
3831 /* Patch in the call to call the following code (done at
3834 tmpmcodeptr = cd->mcodeptr; /* save current mcodeptr */
3835 cd->mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */
3837 M_BSR(REG_ITMP3, tmpmcodeptr - (savedmcodeptr + 1));
3839 cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
3841 /* create stack frame */
3843 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
3845 /* move return address onto stack */
3847 M_AST(REG_ITMP3, REG_SP, 5 * 8);
3849 /* move pointer to java_objectheader onto stack */
3851 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3852 /* create a virtual java_objectheader */
3854 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
3855 disp = dseg_addaddress(cd, NULL); /* vftbl */
3857 M_LDA(REG_ITMP3, REG_PV, disp);
3858 M_AST(REG_ITMP3, REG_SP, 4 * 8);
3863 /* move machine code onto stack */
3865 disp = dseg_adds4(cd, mcode);
3866 M_ILD(REG_ITMP3, REG_PV, disp);
3867 M_IST(REG_ITMP3, REG_SP, 3 * 8);
3869 /* move class/method/field reference onto stack */
3871 disp = dseg_addaddress(cd, pref->ref);
3872 M_ALD(REG_ITMP3, REG_PV, disp);
3873 M_AST(REG_ITMP3, REG_SP, 2 * 8);
3875 /* move data segment displacement onto stack */
3877 disp = dseg_adds4(cd, pref->disp);
3878 M_ILD(REG_ITMP3, REG_PV, disp);
3879 M_IST(REG_ITMP3, REG_SP, 1 * 8);
3881 /* move patcher function pointer onto stack */
3883 disp = dseg_addaddress(cd, pref->patcher);
3884 M_ALD(REG_ITMP3, REG_PV, disp);
3885 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3887 disp = dseg_addaddress(cd, asm_wrapper_patcher);
3888 M_ALD(REG_ITMP3, REG_PV, disp);
3889 M_JMP(REG_ZERO, REG_ITMP3);
3892 /* generate replacement-out stubs */
3897 replacementpoint = jd->code->rplpoints;
3899 for (i = 0; i < jd->code->rplpointcount; ++i, ++replacementpoint) {
3900 /* check code segment size */
3904 /* note start of stub code */
3906 replacementpoint->outcode = (u1*) (ptrint)((u1 *) cd->mcodeptr - cd->mcodebase);
3908 /* make machine code for patching */
3910 tmpmcodeptr = cd->mcodeptr;
3911 cd->mcodeptr = (u4 *) &(replacementpoint->mcode);
3913 disp = (ptrint)((s4*)replacementpoint->outcode - (s4*)replacementpoint->pc) - 1;
3916 cd->mcodeptr = tmpmcodeptr;
3918 /* create stack frame - 16-byte aligned */
3920 M_LSUB_IMM(REG_SP, 2 * 8, REG_SP);
3922 /* push address of `rplpoint` struct */
3924 disp = dseg_addaddress(cd, replacementpoint);
3925 M_ALD(REG_ITMP3, REG_PV, disp);
3926 M_AST(REG_ITMP3, REG_SP, 0 * 8);
3928 /* jump to replacement function */
3930 disp = dseg_addaddress(cd, asm_replacement_out);
3931 M_ALD(REG_ITMP3, REG_PV, disp);
3932 M_JMP(REG_ZERO, REG_ITMP3);
3939 /* everything's ok */
3945 /* createcompilerstub **********************************************************
3947 Creates a stub routine which calls the compiler.
3949 *******************************************************************************/
3951 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
3952 #define COMPILERSTUB_CODESIZE 3 * 4
3954 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
3957 u1 *createcompilerstub(methodinfo *m)
3959 u1 *s; /* memory to hold the stub */
3962 s4 dumpsize; /* code generation pointer */
3964 s = CNEW(u1, COMPILERSTUB_SIZE);
3966 /* set data pointer and code pointer */
3969 s = s + COMPILERSTUB_DATASIZE;
3971 /* mark start of dump memory area */
3973 dumpsize = dump_size();
3975 cd = DNEW(codegendata);
3976 cd->mcodeptr = (u4 *) s;
3978 /* Store the methodinfo* in the same place as in the methodheader
3979 for compiled methods. */
3981 d[0] = (ptrint) asm_call_jit_compiler;
3984 /* code for the stub */
3986 M_ALD(REG_ITMP1, REG_PV, -1 * 8); /* load methodinfo pointer */
3987 M_ALD(REG_PV, REG_PV, -2 * 8); /* load pointer to the compiler */
3988 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
3990 #if defined(ENABLE_STATISTICS)
3992 count_cstub_len += COMPILERSTUB_SIZE;
3995 /* release dump area */
3997 dump_release(dumpsize);
4003 /* createnativestub ************************************************************
4005 Creates a stub routine which calls a native method.
4007 *******************************************************************************/
4009 u1 *createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
4014 s4 stackframesize; /* size of stackframe if needed */
4017 s4 i, j; /* count variables */
4020 s4 funcdisp; /* displacement of the function */
4022 /* get required compiler data */
4028 /* initialize variables */
4031 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4033 /* calculate stack frame size */
4036 1 + /* return address */
4037 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4038 sizeof(localref_table) / SIZEOF_VOID_P +
4039 1 + /* methodinfo for call trace */
4040 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4043 /* create method header */
4045 (void) dseg_addaddress(cd, m); /* MethodPointer */
4046 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4047 (void) dseg_adds4(cd, 0); /* IsSync */
4048 (void) dseg_adds4(cd, 0); /* IsLeaf */
4049 (void) dseg_adds4(cd, 0); /* IntSave */
4050 (void) dseg_adds4(cd, 0); /* FltSave */
4051 (void) dseg_addlinenumbertablesize(cd);
4052 (void) dseg_adds4(cd, 0); /* ExTableSize */
4054 /* generate stub code */
4056 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4057 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4059 /* call trace function */
4061 #if !defined(NDEBUG)
4062 if (opt_verbosecall) {
4063 /* save integer argument registers */
4065 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4066 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4067 M_LST(rd->argintregs[i], REG_SP, j * 8);
4072 /* save and copy float arguments into integer registers */
4074 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4075 t = md->paramtypes[i].type;
4077 if (IS_FLT_DBL_TYPE(t)) {
4078 if (IS_2_WORD_TYPE(t)) {
4079 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4080 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4082 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4083 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4089 disp = dseg_addaddress(cd, m);
4090 M_ALD(REG_ITMP1, REG_PV, disp);
4091 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4092 disp = dseg_addaddress(cd, builtin_trace_args);
4093 M_ALD(REG_PV, REG_PV, disp);
4094 M_JSR(REG_RA, REG_PV);
4095 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
4096 M_LDA(REG_PV, REG_RA, -disp);
4098 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4099 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4100 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4105 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4106 t = md->paramtypes[i].type;
4108 if (IS_FLT_DBL_TYPE(t)) {
4109 if (IS_2_WORD_TYPE(t)) {
4110 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4112 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4118 #endif /* !defined(NDEBUG) */
4120 /* get function address (this must happen before the stackframeinfo) */
4122 funcdisp = dseg_addaddress(cd, f);
4124 #if !defined(WITH_STATIC_CLASSPATH)
4126 codegen_addpatchref(cd, PATCHER_resolve_native, m, funcdisp);
4128 if (opt_showdisassemble)
4133 /* save integer and float argument registers */
4135 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4136 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4137 M_LST(rd->argintregs[i], REG_SP, j * 8);
4142 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4143 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4144 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4149 /* prepare data structures for native function call */
4151 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4152 M_MOV(REG_PV, rd->argintregs[1]);
4153 M_LDA(rd->argintregs[2], REG_SP, stackframesize * 8);
4154 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4155 disp = dseg_addaddress(cd, codegen_start_native_call);
4156 M_ALD(REG_PV, REG_PV, disp);
4157 M_JSR(REG_RA, REG_PV);
4158 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
4159 M_LDA(REG_PV, REG_RA, -disp);
4161 /* restore integer and float argument registers */
4163 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4164 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4165 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4170 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4171 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4172 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4177 /* copy or spill arguments to new locations */
4179 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4180 t = md->paramtypes[i].type;
4182 if (IS_INT_LNG_TYPE(t)) {
4183 if (!md->params[i].inmemory) {
4184 s1 = rd->argintregs[md->params[i].regoff];
4186 if (!nmd->params[j].inmemory) {
4187 s2 = rd->argintregs[nmd->params[j].regoff];
4191 s2 = nmd->params[j].regoff;
4192 M_LST(s1, REG_SP, s2 * 8);
4196 s1 = md->params[i].regoff + stackframesize;
4197 s2 = nmd->params[j].regoff;
4198 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4199 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4203 if (!md->params[i].inmemory) {
4204 s1 = rd->argfltregs[md->params[i].regoff];
4206 if (!nmd->params[j].inmemory) {
4207 s2 = rd->argfltregs[nmd->params[j].regoff];
4211 s2 = nmd->params[j].regoff;
4212 if (IS_2_WORD_TYPE(t))
4213 M_DST(s1, REG_SP, s2 * 8);
4215 M_FST(s1, REG_SP, s2 * 8);
4219 s1 = md->params[i].regoff + stackframesize;
4220 s2 = nmd->params[j].regoff;
4221 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4222 if (IS_2_WORD_TYPE(t))
4223 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4225 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4230 /* put class into second argument register */
4232 if (m->flags & ACC_STATIC) {
4233 disp = dseg_addaddress(cd, m->class);
4234 M_ALD(rd->argintregs[1], REG_PV, disp);
4237 /* put env into first argument register */
4239 disp = dseg_addaddress(cd, _Jv_env);
4240 M_ALD(rd->argintregs[0], REG_PV, disp);
4242 /* do the native function call */
4244 M_ALD(REG_PV, REG_PV, funcdisp);
4245 M_JSR(REG_RA, REG_PV); /* call native method */
4246 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
4247 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4249 /* save return value */
4251 if (IS_INT_LNG_TYPE(md->returntype.type))
4252 M_LST(REG_RESULT, REG_SP, 0 * 8);
4254 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4256 /* remove native stackframe info */
4258 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4259 disp = dseg_addaddress(cd, codegen_finish_native_call);
4260 M_ALD(REG_PV, REG_PV, disp);
4261 M_JSR(REG_RA, REG_PV);
4262 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
4263 M_LDA(REG_PV, REG_RA, -disp);
4265 /* call finished trace */
4267 #if !defined(NDEBUG)
4268 if (opt_verbosecall) {
4269 /* just restore the value we need, don't care about the other */
4271 if (IS_INT_LNG_TYPE(md->returntype.type))
4272 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4274 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4276 disp = dseg_addaddress(cd, m);
4277 M_ALD(rd->argintregs[0], REG_PV, disp);
4279 M_MOV(REG_RESULT, rd->argintregs[1]);
4280 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4281 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4283 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4284 M_ALD(REG_PV, REG_PV, disp);
4285 M_JSR(REG_RA, REG_PV);
4286 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
4287 M_LDA(REG_PV, REG_RA, -disp);
4289 #endif /* !defined(NDEBUG) */
4291 /* check for exception */
4293 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4294 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4295 M_ALD(REG_PV, REG_PV, disp);
4296 M_JSR(REG_RA, REG_PV);
4297 disp = (s4) ((u1 *) cd->mcodeptr - cd->mcodebase);
4298 M_LDA(REG_PV, REG_RA, -disp);
4299 M_MOV(REG_RESULT, REG_ITMP3);
4301 disp = dseg_addaddress(cd, &_exceptionptr);
4302 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4304 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4306 /* restore return value */
4308 if (IS_INT_LNG_TYPE(md->returntype.type))
4309 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4311 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4313 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4315 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4316 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4317 M_RET(REG_ZERO, REG_RA); /* return to caller */
4319 /* handle exception */
4321 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4323 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4324 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4326 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4328 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4329 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4330 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4333 /* process patcher calls **************************************************/
4341 /* there can only be one <clinit> ref entry */
4343 pref = cd->patchrefs;
4345 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4346 /* Get machine code which is patched back in later. The
4347 call is 1 instruction word long. */
4349 savedmcodeptr = (u4 *) (cd->mcodebase + pref->branchpos);
4350 mcode = (u4) *savedmcodeptr;
4352 /* patch in the call to call the following code (done at compile */
4355 tmpmcodeptr = cd->mcodeptr; /* save current mcodeptr */
4356 cd->mcodeptr = savedmcodeptr; /* set mcodeptr to patch position */
4358 M_BSR(REG_ITMP3, tmpmcodeptr - (savedmcodeptr + 1));
4360 cd->mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4362 /* create stack frame */
4364 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4366 /* move return address onto stack */
4368 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4370 /* move pointer to java_objectheader onto stack */
4372 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4373 /* create a virtual java_objectheader */
4375 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4376 disp = dseg_addaddress(cd, NULL); /* vftbl */
4378 M_LDA(REG_ITMP3, REG_PV, disp);
4379 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4381 M_AST(REG_ZERO, REG_SP, 4 * 8);
4384 /* move machine code onto stack */
4386 disp = dseg_adds4(cd, mcode);
4387 M_ILD(REG_ITMP3, REG_PV, disp);
4388 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4390 /* move class/method/field reference onto stack */
4392 disp = dseg_addaddress(cd, pref->ref);
4393 M_ALD(REG_ITMP3, REG_PV, disp);
4394 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4396 /* move data segment displacement onto stack */
4398 disp = dseg_adds4(cd, pref->disp);
4399 M_ILD(REG_ITMP3, REG_PV, disp);
4400 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4402 /* move patcher function pointer onto stack */
4404 disp = dseg_addaddress(cd, pref->patcher);
4405 M_ALD(REG_ITMP3, REG_PV, disp);
4406 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4408 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4409 M_ALD(REG_ITMP3, REG_PV, disp);
4410 M_JMP(REG_ZERO, REG_ITMP3);
4416 return jd->code->entrypoint;
4421 * These are local overrides for various environment variables in Emacs.
4422 * Please do not remove this and leave it at the end of the file, where
4423 * Emacs will automagically detect them.
4424 * ---------------------------------------------------------------------
4427 * indent-tabs-mode: t
4431 * vim:noexpandtab:sw=4:ts=4: