1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
34 $Id: codegen.c 3664 2005-11-11 14:27:09Z twisti $
48 #include "vm/jit/alpha/arch.h"
49 #include "vm/jit/alpha/codegen.h"
51 #include "cacao/cacao.h"
52 #include "native/jni.h"
53 #include "native/native.h"
54 #include "vm/builtin.h"
55 #include "vm/global.h"
56 #include "vm/loader.h"
57 #include "vm/stringlocal.h"
58 #include "vm/tables.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/codegen.inc"
61 #include "vm/jit/jit.h"
64 # include "vm/jit/lsra.h"
65 # include "vm/jit/lsra.inc"
68 #include "vm/jit/parse.h"
69 #include "vm/jit/patcher.h"
70 #include "vm/jit/reg.h"
71 #include "vm/jit/reg.inc"
74 /* codegen *********************************************************************
76 Generates machine code.
78 *******************************************************************************/
80 bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
82 s4 len, s1, s2, s3, d, disp;
91 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
92 builtintable_entry *bte;
95 /* prevent compiler warnings */
106 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
108 /* space to save used callee saved registers */
110 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
111 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
113 parentargs_base = rd->memuse + savedregs_num;
115 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
117 if (checksync && (m->flags & ACC_SYNCHRONIZED))
122 /* create method header */
124 (void) dseg_addaddress(cd, m); /* MethodPointer */
125 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
127 #if defined(USE_THREADS)
129 /* IsSync contains the offset relative to the stack pointer for the
130 argument of monitor_exit used in the exception handler. Since the
131 offset could be zero and give a wrong meaning of the flag it is
135 if (checksync && (m->flags & ACC_SYNCHRONIZED))
136 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
141 (void) dseg_adds4(cd, 0); /* IsSync */
143 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
144 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */
145 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */
147 dseg_addlinenumbertablesize(cd);
149 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
151 /* create exception table */
153 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
154 dseg_addtarget(cd, ex->start);
155 dseg_addtarget(cd, ex->end);
156 dseg_addtarget(cd, ex->handler);
157 (void) dseg_addaddress(cd, ex->catchtype.cls);
160 /* initialize mcode variables */
162 mcodeptr = (s4 *) cd->mcodebase;
163 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
164 MCODECHECK(128 + m->paramcount);
166 /* create stack frame (if necessary) */
168 if (parentargs_base) {
169 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
172 /* save return address and used callee saved registers */
175 if (!m->isleafmethod) {
176 p--; M_AST(REG_RA, REG_SP, p * 8);
178 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
179 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
181 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
182 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
185 /* take arguments out of register or stack frame */
189 for (p = 0, l = 0; p < md->paramcount; p++) {
190 t = md->paramtypes[p].type;
191 var = &(rd->locals[l][t]);
193 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
197 s1 = md->params[p].regoff;
198 if (IS_INT_LNG_TYPE(t)) { /* integer args */
199 if (!md->params[p].inmemory) { /* register arguments */
200 s2 = rd->argintregs[s1];
201 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
202 M_INTMOVE(s2, var->regoff);
204 } else { /* reg arg -> spilled */
205 M_LST(s2, REG_SP, var->regoff * 8);
208 } else { /* stack arguments */
209 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
210 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
212 } else { /* stack arg -> spilled */
213 var->regoff = parentargs_base + s1;
217 } else { /* floating args */
218 if (!md->params[p].inmemory) { /* register arguments */
219 s2 = rd->argfltregs[s1];
220 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
221 M_FLTMOVE(s2, var->regoff);
223 } else { /* reg arg -> spilled */
224 M_DST(s2, REG_SP, var->regoff * 8);
227 } else { /* stack arguments */
228 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
229 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
231 } else { /* stack-arg -> spilled */
232 var->regoff = parentargs_base + s1;
238 /* call monitorenter function */
240 #if defined(USE_THREADS)
241 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
242 /* stack offset for monitor argument */
247 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
249 for (p = 0; p < INT_ARG_CNT; p++)
250 M_LST(rd->argintregs[p], REG_SP, p * 8);
252 for (p = 0; p < FLT_ARG_CNT; p++)
253 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
255 s1 += INT_ARG_CNT + FLT_ARG_CNT;
258 /* decide which monitor enter function to call */
260 if (m->flags & ACC_STATIC) {
261 disp = dseg_addaddress(cd, m->class);
262 M_ALD(REG_ITMP1, REG_PV, disp);
263 M_AST(REG_ITMP1, REG_SP, s1 * 8);
264 M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
265 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
266 M_ALD(REG_PV, REG_PV, disp);
267 M_JSR(REG_RA, REG_PV);
268 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
269 M_LDA(REG_PV, REG_RA, disp);
272 M_BEQZ(rd->argintregs[0], 0);
273 codegen_addxnullrefs(cd, mcodeptr);
274 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
275 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
276 M_ALD(REG_PV, REG_PV, disp);
277 M_JSR(REG_RA, REG_PV);
278 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
279 M_LDA(REG_PV, REG_RA, disp);
283 for (p = 0; p < INT_ARG_CNT; p++)
284 M_LLD(rd->argintregs[p], REG_SP, p * 8);
286 for (p = 0; p < FLT_ARG_CNT; p++)
287 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
289 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
294 /* call trace function */
297 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
298 M_AST(REG_RA, REG_SP, 1 * 8);
300 /* save integer argument registers */
302 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
303 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
305 /* save and copy float arguments into integer registers */
307 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
308 t = md->paramtypes[p].type;
310 if (IS_FLT_DBL_TYPE(t)) {
311 if (IS_2_WORD_TYPE(t)) {
312 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
315 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
318 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
321 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
325 disp = dseg_addaddress(cd, m);
326 M_ALD(REG_ITMP1, REG_PV, disp);
327 M_AST(REG_ITMP1, REG_SP, 0 * 8);
328 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
329 M_ALD(REG_PV, REG_PV, disp);
330 M_JSR(REG_RA, REG_PV);
331 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
332 M_LDA(REG_PV, REG_RA, disp);
333 M_ALD(REG_RA, REG_SP, 1 * 8);
335 /* restore integer argument registers */
337 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
338 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
340 /* restore float argument registers */
342 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
343 t = md->paramtypes[p].type;
345 if (IS_FLT_DBL_TYPE(t)) {
346 if (IS_2_WORD_TYPE(t)) {
347 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
350 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
354 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
358 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
363 /* end of header generation */
365 /* walk through all basic blocks */
367 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
369 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
371 if (bptr->flags >= BBREACHED) {
373 /* branch resolving */
377 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
378 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
379 brefs->branchpos, bptr->mpc);
383 /* copy interface registers to their destination */
390 while (src != NULL) {
392 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
393 /* d = reg_of_var(m, src, REG_ITMP1); */
394 if (!(src->flags & INMEMORY))
398 M_INTMOVE(REG_ITMP1, d);
399 store_reg_to_var_int(src, d);
405 while (src != NULL) {
407 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
408 d = reg_of_var(rd, src, REG_ITMP1);
409 M_INTMOVE(REG_ITMP1, d);
410 store_reg_to_var_int(src, d);
412 d = reg_of_var(rd, src, REG_IFTMP);
413 if ((src->varkind != STACKVAR)) {
415 if (IS_FLT_DBL_TYPE(s2)) {
416 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
417 s1 = rd->interfaces[len][s2].regoff;
420 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
422 store_reg_to_var_flt(src, d);
425 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
426 s1 = rd->interfaces[len][s2].regoff;
429 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
431 store_reg_to_var_int(src, d);
441 /* walk through all instructions */
446 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
447 if (iptr->line != currentline) {
448 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
449 currentline = iptr->line;
452 MCODECHECK(64); /* an instruction usually needs < 64 words */
455 case ICMD_INLINE_START:
456 case ICMD_INLINE_END:
459 case ICMD_NOP: /* ... ==> ... */
462 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
464 var_to_reg_int(s1, src, REG_ITMP1);
466 codegen_addxnullrefs(cd, mcodeptr);
469 /* constant operations ************************************************/
471 case ICMD_ICONST: /* ... ==> ..., constant */
472 /* op1 = 0, val.i = constant */
474 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
475 ICONST(d, iptr->val.i);
476 store_reg_to_var_int(iptr->dst, d);
479 case ICMD_LCONST: /* ... ==> ..., constant */
480 /* op1 = 0, val.l = constant */
482 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
483 LCONST(d, iptr->val.l);
484 store_reg_to_var_int(iptr->dst, d);
487 case ICMD_FCONST: /* ... ==> ..., constant */
488 /* op1 = 0, val.f = constant */
490 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
491 disp = dseg_addfloat(cd, iptr->val.f);
492 M_FLD(d, REG_PV, disp);
493 store_reg_to_var_flt(iptr->dst, d);
496 case ICMD_DCONST: /* ... ==> ..., constant */
497 /* op1 = 0, val.d = constant */
499 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
500 disp = dseg_adddouble(cd, iptr->val.d);
501 M_DLD(d, REG_PV, disp);
502 store_reg_to_var_flt(iptr->dst, d);
505 case ICMD_ACONST: /* ... ==> ..., constant */
506 /* op1 = 0, val.a = constant */
508 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
510 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
511 disp = dseg_addaddress(cd, iptr->val.a);
513 codegen_addpatchref(cd, mcodeptr,
515 (unresolved_class *) iptr->target, disp);
517 if (opt_showdisassemble)
520 M_ALD(d, REG_PV, disp);
523 if (iptr->val.a == NULL) {
524 M_INTMOVE(REG_ZERO, d);
526 disp = dseg_addaddress(cd, iptr->val.a);
527 M_ALD(d, REG_PV, disp);
530 store_reg_to_var_int(iptr->dst, d);
534 /* load/store operations **********************************************/
536 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
537 case ICMD_LLOAD: /* op1 = local variable */
540 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
541 if ((iptr->dst->varkind == LOCALVAR) &&
542 (iptr->dst->varnum == iptr->op1))
544 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
545 if (var->flags & INMEMORY) {
546 M_LLD(d, REG_SP, var->regoff * 8);
548 M_INTMOVE(var->regoff, d);
550 store_reg_to_var_int(iptr->dst, d);
553 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
554 case ICMD_DLOAD: /* op1 = local variable */
556 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
557 if ((iptr->dst->varkind == LOCALVAR) &&
558 (iptr->dst->varnum == iptr->op1))
560 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
561 if (var->flags & INMEMORY) {
562 M_DLD(d, REG_SP, var->regoff * 8);
564 M_FLTMOVE(var->regoff, d);
566 store_reg_to_var_flt(iptr->dst, d);
570 case ICMD_ISTORE: /* ..., value ==> ... */
571 case ICMD_LSTORE: /* op1 = local variable */
574 if ((src->varkind == LOCALVAR) &&
575 (src->varnum == iptr->op1))
577 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
578 if (var->flags & INMEMORY) {
579 var_to_reg_int(s1, src, REG_ITMP1);
580 M_LST(s1, REG_SP, var->regoff * 8);
582 var_to_reg_int(s1, src, var->regoff);
583 M_INTMOVE(s1, var->regoff);
587 case ICMD_FSTORE: /* ..., value ==> ... */
588 case ICMD_DSTORE: /* op1 = local variable */
590 if ((src->varkind == LOCALVAR) &&
591 (src->varnum == iptr->op1))
593 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
594 if (var->flags & INMEMORY) {
595 var_to_reg_flt(s1, src, REG_FTMP1);
596 M_DST(s1, REG_SP, var->regoff * 8);
598 var_to_reg_flt(s1, src, var->regoff);
599 M_FLTMOVE(s1, var->regoff);
604 /* pop/dup/swap operations ********************************************/
606 /* attention: double and longs are only one entry in CACAO ICMDs */
608 case ICMD_POP: /* ..., value ==> ... */
609 case ICMD_POP2: /* ..., value, value ==> ... */
612 case ICMD_DUP: /* ..., a ==> ..., a, a */
613 M_COPY(src, iptr->dst);
616 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
618 M_COPY(src, iptr->dst);
619 M_COPY(src->prev, iptr->dst->prev);
620 M_COPY(iptr->dst, iptr->dst->prev->prev);
623 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
625 M_COPY(src, iptr->dst);
626 M_COPY(src->prev, iptr->dst->prev);
627 M_COPY(src->prev->prev, iptr->dst->prev->prev);
628 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
631 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
633 M_COPY(src, iptr->dst);
634 M_COPY(src->prev, iptr->dst->prev);
637 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
639 M_COPY(src, iptr->dst);
640 M_COPY(src->prev, iptr->dst->prev);
641 M_COPY(src->prev->prev, iptr->dst->prev->prev);
642 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
643 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
646 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
648 M_COPY(src, iptr->dst);
649 M_COPY(src->prev, iptr->dst->prev);
650 M_COPY(src->prev->prev, iptr->dst->prev->prev);
651 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
652 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
653 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
656 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
658 M_COPY(src, iptr->dst->prev);
659 M_COPY(src->prev, iptr->dst);
663 /* integer operations *************************************************/
665 case ICMD_INEG: /* ..., value ==> ..., - value */
667 var_to_reg_int(s1, src, REG_ITMP1);
668 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
669 M_ISUB(REG_ZERO, s1, d);
670 store_reg_to_var_int(iptr->dst, d);
673 case ICMD_LNEG: /* ..., value ==> ..., - value */
675 var_to_reg_int(s1, src, REG_ITMP1);
676 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
677 M_LSUB(REG_ZERO, s1, d);
678 store_reg_to_var_int(iptr->dst, d);
681 case ICMD_I2L: /* ..., value ==> ..., value */
683 var_to_reg_int(s1, src, REG_ITMP1);
684 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
686 store_reg_to_var_int(iptr->dst, d);
689 case ICMD_L2I: /* ..., value ==> ..., value */
691 var_to_reg_int(s1, src, REG_ITMP1);
692 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
693 M_IADD(s1, REG_ZERO, d);
694 store_reg_to_var_int(iptr->dst, d);
697 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
699 var_to_reg_int(s1, src, REG_ITMP1);
700 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
701 if (has_ext_instr_set) {
704 M_SLL_IMM(s1, 56, d);
705 M_SRA_IMM( d, 56, d);
707 store_reg_to_var_int(iptr->dst, d);
710 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
712 var_to_reg_int(s1, src, REG_ITMP1);
713 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
715 store_reg_to_var_int(iptr->dst, d);
718 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
720 var_to_reg_int(s1, src, REG_ITMP1);
721 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
722 if (has_ext_instr_set) {
725 M_SLL_IMM(s1, 48, d);
726 M_SRA_IMM( d, 48, d);
728 store_reg_to_var_int(iptr->dst, d);
732 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
734 var_to_reg_int(s1, src->prev, REG_ITMP1);
735 var_to_reg_int(s2, src, REG_ITMP2);
736 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
738 store_reg_to_var_int(iptr->dst, d);
741 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
742 /* val.i = constant */
744 var_to_reg_int(s1, src, REG_ITMP1);
745 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
746 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
747 M_IADD_IMM(s1, iptr->val.i, d);
749 ICONST(REG_ITMP2, iptr->val.i);
750 M_IADD(s1, REG_ITMP2, d);
752 store_reg_to_var_int(iptr->dst, d);
755 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
757 var_to_reg_int(s1, src->prev, REG_ITMP1);
758 var_to_reg_int(s2, src, REG_ITMP2);
759 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
761 store_reg_to_var_int(iptr->dst, d);
764 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
765 /* val.l = constant */
767 var_to_reg_int(s1, src, REG_ITMP1);
768 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
769 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
770 M_LADD_IMM(s1, iptr->val.l, d);
772 LCONST(REG_ITMP2, iptr->val.l);
773 M_LADD(s1, REG_ITMP2, d);
775 store_reg_to_var_int(iptr->dst, d);
778 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
780 var_to_reg_int(s1, src->prev, REG_ITMP1);
781 var_to_reg_int(s2, src, REG_ITMP2);
782 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
784 store_reg_to_var_int(iptr->dst, d);
787 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
788 /* val.i = constant */
790 var_to_reg_int(s1, src, REG_ITMP1);
791 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
792 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
793 M_ISUB_IMM(s1, iptr->val.i, d);
795 ICONST(REG_ITMP2, iptr->val.i);
796 M_ISUB(s1, REG_ITMP2, d);
798 store_reg_to_var_int(iptr->dst, d);
801 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
803 var_to_reg_int(s1, src->prev, REG_ITMP1);
804 var_to_reg_int(s2, src, REG_ITMP2);
805 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
807 store_reg_to_var_int(iptr->dst, d);
810 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
811 /* val.l = constant */
813 var_to_reg_int(s1, src, REG_ITMP1);
814 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
815 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
816 M_LSUB_IMM(s1, iptr->val.l, d);
818 LCONST(REG_ITMP2, iptr->val.l);
819 M_LSUB(s1, REG_ITMP2, d);
821 store_reg_to_var_int(iptr->dst, d);
824 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
826 var_to_reg_int(s1, src->prev, REG_ITMP1);
827 var_to_reg_int(s2, src, REG_ITMP2);
828 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
830 store_reg_to_var_int(iptr->dst, d);
833 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
834 /* val.i = constant */
836 var_to_reg_int(s1, src, REG_ITMP1);
837 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
838 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
839 M_IMUL_IMM(s1, iptr->val.i, d);
841 ICONST(REG_ITMP2, iptr->val.i);
842 M_IMUL(s1, REG_ITMP2, d);
844 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
849 var_to_reg_int(s1, src->prev, REG_ITMP1);
850 var_to_reg_int(s2, src, REG_ITMP2);
851 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
853 store_reg_to_var_int(iptr->dst, d);
856 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
857 /* val.l = constant */
859 var_to_reg_int(s1, src, REG_ITMP1);
860 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
861 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
862 M_LMUL_IMM(s1, iptr->val.l, d);
864 LCONST(REG_ITMP2, iptr->val.l);
865 M_LMUL(s1, REG_ITMP2, d);
867 store_reg_to_var_int(iptr->dst, d);
870 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
871 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
873 var_to_reg_int(s1, src->prev, REG_ITMP1);
874 var_to_reg_int(s2, src, REG_ITMP2);
875 d = reg_of_var(rd, iptr->dst, REG_RESULT);
877 codegen_addxdivrefs(cd, mcodeptr);
879 M_MOV(s1, rd->argintregs[0]);
880 M_MOV(s2, rd->argintregs[1]);
882 disp = dseg_addaddress(cd, bte->fp);
883 M_ALD(REG_PV, REG_PV, disp);
884 M_JSR(REG_RA, REG_PV);
885 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
886 M_LDA(REG_PV, REG_RA, -disp);
888 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
889 store_reg_to_var_int(iptr->dst, d);
892 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
893 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
895 var_to_reg_int(s1, src->prev, REG_ITMP1);
896 var_to_reg_int(s2, src, REG_ITMP2);
897 d = reg_of_var(rd, iptr->dst, REG_RESULT);
899 codegen_addxdivrefs(cd, mcodeptr);
901 M_MOV(s1, rd->argintregs[0]);
902 M_MOV(s2, rd->argintregs[1]);
904 disp = dseg_addaddress(cd, bte->fp);
905 M_ALD(REG_PV, REG_PV, disp);
906 M_JSR(REG_RA, REG_PV);
907 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
908 M_LDA(REG_PV, REG_RA, -disp);
910 M_INTMOVE(REG_RESULT, d);
911 store_reg_to_var_int(iptr->dst, d);
914 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
915 case ICMD_LDIVPOW2: /* val.i = constant */
917 var_to_reg_int(s1, src, REG_ITMP1);
918 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
919 if (iptr->val.i <= 15) {
920 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
921 M_CMOVGE(s1, s1, REG_ITMP2);
923 M_SRA_IMM(s1, 63, REG_ITMP2);
924 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
925 M_LADD(s1, REG_ITMP2, REG_ITMP2);
927 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
928 store_reg_to_var_int(iptr->dst, d);
931 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
933 var_to_reg_int(s1, src->prev, REG_ITMP1);
934 var_to_reg_int(s2, src, REG_ITMP2);
935 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
936 M_AND_IMM(s2, 0x1f, REG_ITMP3);
937 M_SLL(s1, REG_ITMP3, d);
938 M_IADD(d, REG_ZERO, d);
939 store_reg_to_var_int(iptr->dst, d);
942 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
943 /* val.i = constant */
945 var_to_reg_int(s1, src, REG_ITMP1);
946 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
947 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
948 M_IADD(d, REG_ZERO, d);
949 store_reg_to_var_int(iptr->dst, d);
952 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
954 var_to_reg_int(s1, src->prev, REG_ITMP1);
955 var_to_reg_int(s2, src, REG_ITMP2);
956 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
957 M_AND_IMM(s2, 0x1f, REG_ITMP3);
958 M_SRA(s1, REG_ITMP3, d);
959 store_reg_to_var_int(iptr->dst, d);
962 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
963 /* val.i = constant */
965 var_to_reg_int(s1, src, REG_ITMP1);
966 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
967 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
968 store_reg_to_var_int(iptr->dst, d);
971 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
973 var_to_reg_int(s1, src->prev, REG_ITMP1);
974 var_to_reg_int(s2, src, REG_ITMP2);
975 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
976 M_AND_IMM(s2, 0x1f, REG_ITMP2);
978 M_SRL(d, REG_ITMP2, d);
979 M_IADD(d, REG_ZERO, d);
980 store_reg_to_var_int(iptr->dst, d);
983 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
984 /* val.i = constant */
986 var_to_reg_int(s1, src, REG_ITMP1);
987 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
989 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
990 M_IADD(d, REG_ZERO, d);
991 store_reg_to_var_int(iptr->dst, d);
994 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
996 var_to_reg_int(s1, src->prev, REG_ITMP1);
997 var_to_reg_int(s2, src, REG_ITMP2);
998 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1000 store_reg_to_var_int(iptr->dst, d);
1003 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
1004 /* val.i = constant */
1006 var_to_reg_int(s1, src, REG_ITMP1);
1007 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1008 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1009 store_reg_to_var_int(iptr->dst, d);
1012 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1014 var_to_reg_int(s1, src->prev, REG_ITMP1);
1015 var_to_reg_int(s2, src, REG_ITMP2);
1016 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1022 /* val.i = constant */
1024 var_to_reg_int(s1, src, REG_ITMP1);
1025 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1026 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1027 store_reg_to_var_int(iptr->dst, d);
1030 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1032 var_to_reg_int(s1, src->prev, REG_ITMP1);
1033 var_to_reg_int(s2, src, REG_ITMP2);
1034 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1036 store_reg_to_var_int(iptr->dst, d);
1039 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1040 /* val.i = constant */
1042 var_to_reg_int(s1, src, REG_ITMP1);
1043 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1044 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1045 store_reg_to_var_int(iptr->dst, d);
1048 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1051 var_to_reg_int(s1, src->prev, REG_ITMP1);
1052 var_to_reg_int(s2, src, REG_ITMP2);
1053 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1055 store_reg_to_var_int(iptr->dst, d);
1058 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1059 /* val.i = constant */
1061 var_to_reg_int(s1, src, REG_ITMP1);
1062 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1063 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1064 M_AND_IMM(s1, iptr->val.i, d);
1065 } else if (iptr->val.i == 0xffff) {
1067 } else if (iptr->val.i == 0xffffff) {
1068 M_ZAPNOT_IMM(s1, 0x07, d);
1070 ICONST(REG_ITMP2, iptr->val.i);
1071 M_AND(s1, REG_ITMP2, d);
1073 store_reg_to_var_int(iptr->dst, d);
1076 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1077 /* val.i = constant */
1079 var_to_reg_int(s1, src, REG_ITMP1);
1080 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1082 M_MOV(s1, REG_ITMP1);
1085 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1086 M_AND_IMM(s1, iptr->val.i, d);
1088 M_ISUB(REG_ZERO, s1, d);
1089 M_AND_IMM(d, iptr->val.i, d);
1090 } else if (iptr->val.i == 0xffff) {
1093 M_ISUB(REG_ZERO, s1, d);
1095 } else if (iptr->val.i == 0xffffff) {
1096 M_ZAPNOT_IMM(s1, 0x07, d);
1098 M_ISUB(REG_ZERO, s1, d);
1099 M_ZAPNOT_IMM(d, 0x07, d);
1101 ICONST(REG_ITMP2, iptr->val.i);
1102 M_AND(s1, REG_ITMP2, d);
1104 M_ISUB(REG_ZERO, s1, d);
1105 M_AND(d, REG_ITMP2, d);
1107 M_ISUB(REG_ZERO, d, d);
1108 store_reg_to_var_int(iptr->dst, d);
1111 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1112 /* val.l = constant */
1114 var_to_reg_int(s1, src, REG_ITMP1);
1115 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1116 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1117 M_AND_IMM(s1, iptr->val.l, d);
1118 } else if (iptr->val.l == 0xffffL) {
1120 } else if (iptr->val.l == 0xffffffL) {
1121 M_ZAPNOT_IMM(s1, 0x07, d);
1122 } else if (iptr->val.l == 0xffffffffL) {
1124 } else if (iptr->val.l == 0xffffffffffL) {
1125 M_ZAPNOT_IMM(s1, 0x1f, d);
1126 } else if (iptr->val.l == 0xffffffffffffL) {
1127 M_ZAPNOT_IMM(s1, 0x3f, d);
1128 } else if (iptr->val.l == 0xffffffffffffffL) {
1129 M_ZAPNOT_IMM(s1, 0x7f, d);
1131 LCONST(REG_ITMP2, iptr->val.l);
1132 M_AND(s1, REG_ITMP2, d);
1134 store_reg_to_var_int(iptr->dst, d);
1137 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1138 /* val.l = constant */
1140 var_to_reg_int(s1, src, REG_ITMP1);
1141 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1143 M_MOV(s1, REG_ITMP1);
1146 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1147 M_AND_IMM(s1, iptr->val.l, d);
1149 M_LSUB(REG_ZERO, s1, d);
1150 M_AND_IMM(d, iptr->val.l, d);
1151 } else if (iptr->val.l == 0xffffL) {
1154 M_LSUB(REG_ZERO, s1, d);
1156 } else if (iptr->val.l == 0xffffffL) {
1157 M_ZAPNOT_IMM(s1, 0x07, d);
1159 M_LSUB(REG_ZERO, s1, d);
1160 M_ZAPNOT_IMM(d, 0x07, d);
1161 } else if (iptr->val.l == 0xffffffffL) {
1164 M_LSUB(REG_ZERO, s1, d);
1166 } else if (iptr->val.l == 0xffffffffffL) {
1167 M_ZAPNOT_IMM(s1, 0x1f, d);
1169 M_LSUB(REG_ZERO, s1, d);
1170 M_ZAPNOT_IMM(d, 0x1f, d);
1171 } else if (iptr->val.l == 0xffffffffffffL) {
1172 M_ZAPNOT_IMM(s1, 0x3f, d);
1174 M_LSUB(REG_ZERO, s1, d);
1175 M_ZAPNOT_IMM(d, 0x3f, d);
1176 } else if (iptr->val.l == 0xffffffffffffffL) {
1177 M_ZAPNOT_IMM(s1, 0x7f, d);
1179 M_LSUB(REG_ZERO, s1, d);
1180 M_ZAPNOT_IMM(d, 0x7f, d);
1182 LCONST(REG_ITMP2, iptr->val.l);
1183 M_AND(s1, REG_ITMP2, d);
1185 M_LSUB(REG_ZERO, s1, d);
1186 M_AND(d, REG_ITMP2, d);
1188 M_LSUB(REG_ZERO, d, d);
1189 store_reg_to_var_int(iptr->dst, d);
1192 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1195 var_to_reg_int(s1, src->prev, REG_ITMP1);
1196 var_to_reg_int(s2, src, REG_ITMP2);
1197 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1199 store_reg_to_var_int(iptr->dst, d);
1202 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1203 /* val.i = constant */
1205 var_to_reg_int(s1, src, REG_ITMP1);
1206 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1207 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1208 M_OR_IMM(s1, iptr->val.i, d);
1210 ICONST(REG_ITMP2, iptr->val.i);
1211 M_OR(s1, REG_ITMP2, d);
1213 store_reg_to_var_int(iptr->dst, d);
1216 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1217 /* val.l = constant */
1219 var_to_reg_int(s1, src, REG_ITMP1);
1220 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1221 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1222 M_OR_IMM(s1, iptr->val.l, d);
1224 LCONST(REG_ITMP2, iptr->val.l);
1225 M_OR(s1, REG_ITMP2, d);
1227 store_reg_to_var_int(iptr->dst, d);
1230 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1233 var_to_reg_int(s1, src->prev, REG_ITMP1);
1234 var_to_reg_int(s2, src, REG_ITMP2);
1235 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1237 store_reg_to_var_int(iptr->dst, d);
1240 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1241 /* val.i = constant */
1243 var_to_reg_int(s1, src, REG_ITMP1);
1244 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1245 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1246 M_XOR_IMM(s1, iptr->val.i, d);
1248 ICONST(REG_ITMP2, iptr->val.i);
1249 M_XOR(s1, REG_ITMP2, d);
1251 store_reg_to_var_int(iptr->dst, d);
1254 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1255 /* val.l = constant */
1257 var_to_reg_int(s1, src, REG_ITMP1);
1258 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1259 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1260 M_XOR_IMM(s1, iptr->val.l, d);
1262 LCONST(REG_ITMP2, iptr->val.l);
1263 M_XOR(s1, REG_ITMP2, d);
1265 store_reg_to_var_int(iptr->dst, d);
1269 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1271 var_to_reg_int(s1, src->prev, REG_ITMP1);
1272 var_to_reg_int(s2, src, REG_ITMP2);
1273 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1274 M_CMPLT(s1, s2, REG_ITMP3);
1275 M_CMPLT(s2, s1, REG_ITMP1);
1276 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1277 store_reg_to_var_int(iptr->dst, d);
1281 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1282 /* op1 = variable, val.i = constant */
1284 var = &(rd->locals[iptr->op1][TYPE_INT]);
1285 if (var->flags & INMEMORY) {
1287 M_LLD(s1, REG_SP, var->regoff * 8);
1290 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1291 M_IADD_IMM(s1, iptr->val.i, s1);
1292 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1293 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1295 M_LDA (s1, s1, iptr->val.i);
1296 M_IADD(s1, REG_ZERO, s1);
1298 if (var->flags & INMEMORY)
1299 M_LST(s1, REG_SP, var->regoff * 8);
1303 /* floating operations ************************************************/
1305 case ICMD_FNEG: /* ..., value ==> ..., - value */
1307 var_to_reg_flt(s1, src, REG_FTMP1);
1308 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1310 store_reg_to_var_flt(iptr->dst, d);
1313 case ICMD_DNEG: /* ..., value ==> ..., - value */
1315 var_to_reg_flt(s1, src, REG_FTMP1);
1316 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1318 store_reg_to_var_flt(iptr->dst, d);
1321 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1323 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1324 var_to_reg_flt(s2, src, REG_FTMP2);
1325 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1329 if (d == s1 || d == s2) {
1330 M_FADDS(s1, s2, REG_FTMP3);
1332 M_FMOV(REG_FTMP3, d);
1338 store_reg_to_var_flt(iptr->dst, d);
1341 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1343 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1344 var_to_reg_flt(s2, src, REG_FTMP2);
1345 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1349 if (d == s1 || d == s2) {
1350 M_DADDS(s1, s2, REG_FTMP3);
1352 M_FMOV(REG_FTMP3, d);
1358 store_reg_to_var_flt(iptr->dst, d);
1361 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1363 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1364 var_to_reg_flt(s2, src, REG_FTMP2);
1365 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1369 if (d == s1 || d == s2) {
1370 M_FSUBS(s1, s2, REG_FTMP3);
1372 M_FMOV(REG_FTMP3, d);
1378 store_reg_to_var_flt(iptr->dst, d);
1381 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1383 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1384 var_to_reg_flt(s2, src, REG_FTMP2);
1385 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1389 if (d == s1 || d == s2) {
1390 M_DSUBS(s1, s2, REG_FTMP3);
1392 M_FMOV(REG_FTMP3, d);
1398 store_reg_to_var_flt(iptr->dst, d);
1401 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1403 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1404 var_to_reg_flt(s2, src, REG_FTMP2);
1405 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1409 if (d == s1 || d == s2) {
1410 M_FMULS(s1, s2, REG_FTMP3);
1412 M_FMOV(REG_FTMP3, d);
1418 store_reg_to_var_flt(iptr->dst, d);
1421 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1423 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1424 var_to_reg_flt(s2, src, REG_FTMP2);
1425 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1429 if (d == s1 || d == s2) {
1430 M_DMULS(s1, s2, REG_FTMP3);
1432 M_FMOV(REG_FTMP3, d);
1438 store_reg_to_var_flt(iptr->dst, d);
1441 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1443 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1444 var_to_reg_flt(s2, src, REG_FTMP2);
1445 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1449 if (d == s1 || d == s2) {
1450 M_FDIVS(s1, s2, REG_FTMP3);
1452 M_FMOV(REG_FTMP3, d);
1458 store_reg_to_var_flt(iptr->dst, d);
1461 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1463 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1464 var_to_reg_flt(s2, src, REG_FTMP2);
1465 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1469 if (d == s1 || d == s2) {
1470 M_DDIVS(s1, s2, REG_FTMP3);
1472 M_FMOV(REG_FTMP3, d);
1478 store_reg_to_var_flt(iptr->dst, d);
1481 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1483 var_to_reg_int(s1, src, REG_ITMP1);
1484 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1485 disp = dseg_adddouble(cd, 0.0);
1486 M_LST(s1, REG_PV, disp);
1487 M_DLD(d, REG_PV, disp);
1489 store_reg_to_var_flt(iptr->dst, d);
1492 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1494 var_to_reg_int(s1, src, REG_ITMP1);
1495 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1496 disp = dseg_adddouble(cd, 0.0);
1497 M_LST(s1, REG_PV, disp);
1498 M_DLD(d, REG_PV, disp);
1500 store_reg_to_var_flt(iptr->dst, d);
1503 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1505 var_to_reg_flt(s1, src, REG_FTMP1);
1506 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1507 disp = dseg_adddouble(cd, 0.0);
1508 M_CVTDL_C(s1, REG_FTMP2);
1509 M_CVTLI(REG_FTMP2, REG_FTMP3);
1510 M_DST(REG_FTMP3, REG_PV, disp);
1511 M_ILD(d, REG_PV, disp);
1512 store_reg_to_var_int(iptr->dst, d);
1515 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1517 var_to_reg_flt(s1, src, REG_FTMP1);
1518 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1519 disp = dseg_adddouble(cd, 0.0);
1520 M_CVTDL_C(s1, REG_FTMP2);
1521 M_DST(REG_FTMP2, REG_PV, disp);
1522 M_LLD(d, REG_PV, disp);
1523 store_reg_to_var_int(iptr->dst, d);
1526 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1528 var_to_reg_flt(s1, src, REG_FTMP1);
1529 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1532 store_reg_to_var_flt(iptr->dst, d);
1535 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1537 var_to_reg_flt(s1, src, REG_FTMP1);
1538 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1545 store_reg_to_var_flt(iptr->dst, d);
1548 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1550 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1551 var_to_reg_flt(s2, src, REG_FTMP2);
1552 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1554 M_LSUB_IMM(REG_ZERO, 1, d);
1555 M_FCMPEQ(s1, s2, REG_FTMP3);
1556 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1558 M_FCMPLT(s2, s1, REG_FTMP3);
1559 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1560 M_LADD_IMM(REG_ZERO, 1, d);
1562 M_LSUB_IMM(REG_ZERO, 1, d);
1563 M_FCMPEQS(s1, s2, REG_FTMP3);
1565 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1567 M_FCMPLTS(s2, s1, REG_FTMP3);
1569 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1570 M_LADD_IMM(REG_ZERO, 1, d);
1572 store_reg_to_var_int(iptr->dst, d);
1575 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1577 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1578 var_to_reg_flt(s2, src, REG_FTMP2);
1579 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1581 M_LADD_IMM(REG_ZERO, 1, d);
1582 M_FCMPEQ(s1, s2, REG_FTMP3);
1583 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1585 M_FCMPLT(s1, s2, REG_FTMP3);
1586 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1587 M_LSUB_IMM(REG_ZERO, 1, d);
1589 M_LADD_IMM(REG_ZERO, 1, d);
1590 M_FCMPEQS(s1, s2, REG_FTMP3);
1592 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1594 M_FCMPLTS(s1, s2, REG_FTMP3);
1596 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1597 M_LSUB_IMM(REG_ZERO, 1, d);
1599 store_reg_to_var_int(iptr->dst, d);
1603 /* memory operations **************************************************/
1605 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1607 var_to_reg_int(s1, src, REG_ITMP1);
1608 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1609 gen_nullptr_check(s1);
1610 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1611 store_reg_to_var_int(iptr->dst, d);
1614 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1616 var_to_reg_int(s1, src->prev, REG_ITMP1);
1617 var_to_reg_int(s2, src, REG_ITMP2);
1618 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1619 if (iptr->op1 == 0) {
1620 gen_nullptr_check(s1);
1623 if (has_ext_instr_set) {
1624 M_LADD (s2, s1, REG_ITMP1);
1625 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1628 M_LADD(s2, s1, REG_ITMP1);
1629 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1630 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1631 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1632 M_SRA_IMM(d, 56, d);
1634 store_reg_to_var_int(iptr->dst, d);
1637 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1639 var_to_reg_int(s1, src->prev, REG_ITMP1);
1640 var_to_reg_int(s2, src, REG_ITMP2);
1641 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1642 if (iptr->op1 == 0) {
1643 gen_nullptr_check(s1);
1646 if (has_ext_instr_set) {
1647 M_LADD(s2, s1, REG_ITMP1);
1648 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1649 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1651 M_LADD (s2, s1, REG_ITMP1);
1652 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1653 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1654 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1655 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1657 store_reg_to_var_int(iptr->dst, d);
1660 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1662 var_to_reg_int(s1, src->prev, REG_ITMP1);
1663 var_to_reg_int(s2, src, REG_ITMP2);
1664 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1665 if (iptr->op1 == 0) {
1666 gen_nullptr_check(s1);
1669 if (has_ext_instr_set) {
1670 M_LADD(s2, s1, REG_ITMP1);
1671 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1672 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1675 M_LADD(s2, s1, REG_ITMP1);
1676 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1677 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1678 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1679 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1680 M_SRA_IMM(d, 48, d);
1682 store_reg_to_var_int(iptr->dst, d);
1685 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1687 var_to_reg_int(s1, src->prev, REG_ITMP1);
1688 var_to_reg_int(s2, src, REG_ITMP2);
1689 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1690 if (iptr->op1 == 0) {
1691 gen_nullptr_check(s1);
1694 M_S4ADDQ(s2, s1, REG_ITMP1);
1695 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1696 store_reg_to_var_int(iptr->dst, d);
1699 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1701 var_to_reg_int(s1, src->prev, REG_ITMP1);
1702 var_to_reg_int(s2, src, REG_ITMP2);
1703 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1704 if (iptr->op1 == 0) {
1705 gen_nullptr_check(s1);
1708 M_S8ADDQ(s2, s1, REG_ITMP1);
1709 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1710 store_reg_to_var_int(iptr->dst, d);
1713 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1715 var_to_reg_int(s1, src->prev, REG_ITMP1);
1716 var_to_reg_int(s2, src, REG_ITMP2);
1717 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1718 if (iptr->op1 == 0) {
1719 gen_nullptr_check(s1);
1722 M_S4ADDQ(s2, s1, REG_ITMP1);
1723 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1724 store_reg_to_var_flt(iptr->dst, d);
1727 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1729 var_to_reg_int(s1, src->prev, REG_ITMP1);
1730 var_to_reg_int(s2, src, REG_ITMP2);
1731 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1732 if (iptr->op1 == 0) {
1733 gen_nullptr_check(s1);
1736 M_S8ADDQ(s2, s1, REG_ITMP1);
1737 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1738 store_reg_to_var_flt(iptr->dst, d);
1741 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1743 var_to_reg_int(s1, src->prev, REG_ITMP1);
1744 var_to_reg_int(s2, src, REG_ITMP2);
1745 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1746 if (iptr->op1 == 0) {
1747 gen_nullptr_check(s1);
1750 M_SAADDQ(s2, s1, REG_ITMP1);
1751 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1752 store_reg_to_var_int(iptr->dst, d);
1756 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1758 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1759 var_to_reg_int(s2, src->prev, REG_ITMP2);
1760 if (iptr->op1 == 0) {
1761 gen_nullptr_check(s1);
1764 var_to_reg_int(s3, src, REG_ITMP3);
1765 if (has_ext_instr_set) {
1766 M_LADD(s2, s1, REG_ITMP1);
1767 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1769 M_LADD(s2, s1, REG_ITMP1);
1770 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1771 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1772 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1773 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1774 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1775 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1779 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1781 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1782 var_to_reg_int(s2, src->prev, REG_ITMP2);
1783 if (iptr->op1 == 0) {
1784 gen_nullptr_check(s1);
1787 var_to_reg_int(s3, src, REG_ITMP3);
1788 if (has_ext_instr_set) {
1789 M_LADD(s2, s1, REG_ITMP1);
1790 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1791 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1793 M_LADD(s2, s1, REG_ITMP1);
1794 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1795 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1796 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1797 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1798 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1799 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1800 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1804 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1806 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1807 var_to_reg_int(s2, src->prev, REG_ITMP2);
1808 if (iptr->op1 == 0) {
1809 gen_nullptr_check(s1);
1812 var_to_reg_int(s3, src, REG_ITMP3);
1813 if (has_ext_instr_set) {
1814 M_LADD(s2, s1, REG_ITMP1);
1815 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1816 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1818 M_LADD(s2, s1, REG_ITMP1);
1819 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1820 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1821 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1822 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1823 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1824 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1825 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1829 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1831 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1832 var_to_reg_int(s2, src->prev, REG_ITMP2);
1833 if (iptr->op1 == 0) {
1834 gen_nullptr_check(s1);
1837 var_to_reg_int(s3, src, REG_ITMP3);
1838 M_S4ADDQ(s2, s1, REG_ITMP1);
1839 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1842 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1844 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1845 var_to_reg_int(s2, src->prev, REG_ITMP2);
1846 if (iptr->op1 == 0) {
1847 gen_nullptr_check(s1);
1850 var_to_reg_int(s3, src, REG_ITMP3);
1851 M_S8ADDQ(s2, s1, REG_ITMP1);
1852 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1855 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1857 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1858 var_to_reg_int(s2, src->prev, REG_ITMP2);
1859 if (iptr->op1 == 0) {
1860 gen_nullptr_check(s1);
1863 var_to_reg_flt(s3, src, REG_FTMP3);
1864 M_S4ADDQ(s2, s1, REG_ITMP1);
1865 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1868 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1870 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1871 var_to_reg_int(s2, src->prev, REG_ITMP2);
1872 if (iptr->op1 == 0) {
1873 gen_nullptr_check(s1);
1876 var_to_reg_flt(s3, src, REG_FTMP3);
1877 M_S8ADDQ(s2, s1, REG_ITMP1);
1878 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1881 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1883 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1884 var_to_reg_int(s2, src->prev, REG_ITMP2);
1885 if (iptr->op1 == 0) {
1886 gen_nullptr_check(s1);
1889 var_to_reg_int(s3, src, REG_ITMP3);
1891 M_MOV(s1, rd->argintregs[0]);
1892 M_MOV(s3, rd->argintregs[1]);
1893 disp = dseg_addaddress(cd, BUILTIN_canstore);
1894 M_ALD(REG_PV, REG_PV, disp);
1895 M_JSR(REG_RA, REG_PV);
1896 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1897 M_LDA(REG_PV, REG_RA, -disp);
1899 M_BEQZ(REG_RESULT, 0);
1900 codegen_addxstorerefs(cd, mcodeptr);
1902 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1903 var_to_reg_int(s2, src->prev, REG_ITMP2);
1904 var_to_reg_int(s3, src, REG_ITMP3);
1905 M_SAADDQ(s2, s1, REG_ITMP1);
1906 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1910 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1912 var_to_reg_int(s1, src->prev, REG_ITMP1);
1913 var_to_reg_int(s2, src, REG_ITMP2);
1914 if (iptr->op1 == 0) {
1915 gen_nullptr_check(s1);
1918 M_S4ADDQ(s2, s1, REG_ITMP1);
1919 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1922 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1924 var_to_reg_int(s1, src->prev, REG_ITMP1);
1925 var_to_reg_int(s2, src, REG_ITMP2);
1926 if (iptr->op1 == 0) {
1927 gen_nullptr_check(s1);
1930 M_S8ADDQ(s2, s1, REG_ITMP1);
1931 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1934 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1936 var_to_reg_int(s1, src->prev, REG_ITMP1);
1937 var_to_reg_int(s2, src, REG_ITMP2);
1938 if (iptr->op1 == 0) {
1939 gen_nullptr_check(s1);
1942 M_SAADDQ(s2, s1, REG_ITMP1);
1943 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1946 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1948 var_to_reg_int(s1, src->prev, REG_ITMP1);
1949 var_to_reg_int(s2, src, REG_ITMP2);
1950 if (iptr->op1 == 0) {
1951 gen_nullptr_check(s1);
1954 if (has_ext_instr_set) {
1955 M_LADD(s2, s1, REG_ITMP1);
1956 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1959 M_LADD(s2, s1, REG_ITMP1);
1960 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1961 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1962 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1963 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1964 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1965 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1969 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1971 var_to_reg_int(s1, src->prev, REG_ITMP1);
1972 var_to_reg_int(s2, src, REG_ITMP2);
1973 if (iptr->op1 == 0) {
1974 gen_nullptr_check(s1);
1977 if (has_ext_instr_set) {
1978 M_LADD(s2, s1, REG_ITMP1);
1979 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1980 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1983 M_LADD(s2, s1, REG_ITMP1);
1984 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1985 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1986 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1987 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1988 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1989 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1990 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1994 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1996 var_to_reg_int(s1, src->prev, REG_ITMP1);
1997 var_to_reg_int(s2, src, REG_ITMP2);
1998 if (iptr->op1 == 0) {
1999 gen_nullptr_check(s1);
2002 if (has_ext_instr_set) {
2003 M_LADD(s2, s1, REG_ITMP1);
2004 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2005 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2008 M_LADD(s2, s1, REG_ITMP1);
2009 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2010 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2011 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2012 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2013 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2014 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2015 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2020 case ICMD_GETSTATIC: /* ... ==> ..., value */
2021 /* op1 = type, val.a = field address */
2024 disp = dseg_addaddress(cd, 0);
2026 codegen_addpatchref(cd, mcodeptr,
2027 PATCHER_get_putstatic,
2028 (unresolved_field *) iptr->target, disp);
2030 if (opt_showdisassemble)
2035 fieldinfo *fi = iptr->val.a;
2037 disp = dseg_addaddress(cd, &(fi->value));
2039 if (!fi->class->initialized) {
2040 codegen_addpatchref(cd, mcodeptr,
2041 PATCHER_clinit, fi->class, 0);
2043 if (opt_showdisassemble)
2048 M_ALD(REG_ITMP1, REG_PV, disp);
2049 switch (iptr->op1) {
2051 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2052 M_ILD(d, REG_ITMP1, 0);
2053 store_reg_to_var_int(iptr->dst, d);
2056 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2057 M_LLD(d, REG_ITMP1, 0);
2058 store_reg_to_var_int(iptr->dst, d);
2061 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2062 M_ALD(d, REG_ITMP1, 0);
2063 store_reg_to_var_int(iptr->dst, d);
2066 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2067 M_FLD(d, REG_ITMP1, 0);
2068 store_reg_to_var_flt(iptr->dst, d);
2071 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2072 M_DLD(d, REG_ITMP1, 0);
2073 store_reg_to_var_flt(iptr->dst, d);
2078 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2079 /* op1 = type, val.a = field address */
2082 disp = dseg_addaddress(cd, 0);
2084 codegen_addpatchref(cd, mcodeptr,
2085 PATCHER_get_putstatic,
2086 (unresolved_field *) iptr->target, disp);
2088 if (opt_showdisassemble)
2092 fieldinfo *fi = iptr->val.a;
2094 disp = dseg_addaddress(cd, &(fi->value));
2096 if (!fi->class->initialized) {
2097 codegen_addpatchref(cd, mcodeptr,
2098 PATCHER_clinit, fi->class, 0);
2100 if (opt_showdisassemble)
2105 M_ALD(REG_ITMP1, REG_PV, disp);
2106 switch (iptr->op1) {
2108 var_to_reg_int(s2, src, REG_ITMP2);
2109 M_IST(s2, REG_ITMP1, 0);
2112 var_to_reg_int(s2, src, REG_ITMP2);
2113 M_LST(s2, REG_ITMP1, 0);
2116 var_to_reg_int(s2, src, REG_ITMP2);
2117 M_AST(s2, REG_ITMP1, 0);
2120 var_to_reg_flt(s2, src, REG_FTMP2);
2121 M_FST(s2, REG_ITMP1, 0);
2124 var_to_reg_flt(s2, src, REG_FTMP2);
2125 M_DST(s2, REG_ITMP1, 0);
2130 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2131 /* val = value (in current instruction) */
2132 /* op1 = type, val.a = field address (in */
2133 /* following NOP) */
2135 if (!iptr[1].val.a) {
2136 disp = dseg_addaddress(cd, 0);
2138 codegen_addpatchref(cd, mcodeptr,
2139 PATCHER_get_putstatic,
2140 (unresolved_field *) iptr[1].target, disp);
2142 if (opt_showdisassemble)
2146 fieldinfo *fi = iptr[1].val.a;
2148 disp = dseg_addaddress(cd, &(fi->value));
2150 if (!fi->class->initialized) {
2151 codegen_addpatchref(cd, mcodeptr,
2152 PATCHER_clinit, fi->class, 0);
2154 if (opt_showdisassemble)
2159 M_ALD(REG_ITMP1, REG_PV, disp);
2160 switch (iptr->op1) {
2162 M_IST(REG_ZERO, REG_ITMP1, 0);
2165 M_LST(REG_ZERO, REG_ITMP1, 0);
2168 M_AST(REG_ZERO, REG_ITMP1, 0);
2171 M_FST(REG_ZERO, REG_ITMP1, 0);
2174 M_DST(REG_ZERO, REG_ITMP1, 0);
2180 case ICMD_GETFIELD: /* ... ==> ..., value */
2181 /* op1 = type, val.i = field offset */
2183 var_to_reg_int(s1, src, REG_ITMP1);
2184 gen_nullptr_check(s1);
2187 codegen_addpatchref(cd, mcodeptr,
2188 PATCHER_get_putfield,
2189 (unresolved_field *) iptr->target, 0);
2191 if (opt_showdisassemble)
2197 disp = ((fieldinfo *) (iptr->val.a))->offset;
2200 switch (iptr->op1) {
2202 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2204 store_reg_to_var_int(iptr->dst, d);
2207 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2209 store_reg_to_var_int(iptr->dst, d);
2212 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2214 store_reg_to_var_int(iptr->dst, d);
2217 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2219 store_reg_to_var_flt(iptr->dst, d);
2222 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2224 store_reg_to_var_flt(iptr->dst, d);
2229 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2230 /* op1 = type, val.a = field address */
2232 var_to_reg_int(s1, src->prev, REG_ITMP1);
2233 gen_nullptr_check(s1);
2235 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2236 var_to_reg_int(s2, src, REG_ITMP2);
2238 var_to_reg_flt(s2, src, REG_FTMP2);
2242 codegen_addpatchref(cd, mcodeptr,
2243 PATCHER_get_putfield,
2244 (unresolved_field *) iptr->target, 0);
2246 if (opt_showdisassemble)
2252 disp = ((fieldinfo *) (iptr->val.a))->offset;
2255 switch (iptr->op1) {
2257 M_IST(s2, s1, disp);
2260 M_LST(s2, s1, disp);
2263 M_AST(s2, s1, disp);
2266 M_FST(s2, s1, disp);
2269 M_DST(s2, s1, disp);
2274 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2275 /* val = value (in current instruction) */
2276 /* op1 = type, val.a = field address (in */
2277 /* following NOP) */
2279 var_to_reg_int(s1, src, REG_ITMP1);
2280 gen_nullptr_check(s1);
2282 if (!iptr[1].val.a) {
2283 codegen_addpatchref(cd, mcodeptr,
2284 PATCHER_get_putfield,
2285 (unresolved_field *) iptr[1].target, 0);
2287 if (opt_showdisassemble)
2293 disp = ((fieldinfo *) (iptr[1].val.a))->offset;
2296 switch (iptr[1].op1) {
2298 M_IST(REG_ZERO, s1, disp);
2301 M_LST(REG_ZERO, s1, disp);
2304 M_AST(REG_ZERO, s1, disp);
2307 M_FST(REG_ZERO, s1, disp);
2310 M_DST(REG_ZERO, s1, disp);
2316 /* branch operations **************************************************/
2318 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2320 var_to_reg_int(s1, src, REG_ITMP1);
2321 M_INTMOVE(s1, REG_ITMP1_XPTR);
2324 codegen_addpatchref(cd, mcodeptr,
2325 PATCHER_athrow_areturn,
2326 (unresolved_class *) iptr->val.a, 0);
2328 if (opt_showdisassemble)
2332 disp = dseg_addaddress(cd, asm_handle_exception);
2333 M_ALD(REG_ITMP2, REG_PV, disp);
2334 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2335 M_NOP; /* nop ensures that XPC is less than the end */
2336 /* of basic block */
2340 case ICMD_GOTO: /* ... ==> ... */
2341 /* op1 = target JavaVM pc */
2343 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2347 case ICMD_JSR: /* ... ==> ... */
2348 /* op1 = target JavaVM pc */
2350 M_BSR(REG_ITMP1, 0);
2351 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2354 case ICMD_RET: /* ... ==> ... */
2355 /* op1 = local variable */
2357 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2358 if (var->flags & INMEMORY) {
2359 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2360 M_RET(REG_ZERO, REG_ITMP1);
2363 M_RET(REG_ZERO, var->regoff);
2367 case ICMD_IFNULL: /* ..., value ==> ... */
2368 /* op1 = target JavaVM pc */
2370 var_to_reg_int(s1, src, REG_ITMP1);
2372 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2375 case ICMD_IFNONNULL: /* ..., value ==> ... */
2376 /* op1 = target JavaVM pc */
2378 var_to_reg_int(s1, src, REG_ITMP1);
2380 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2383 case ICMD_IFEQ: /* ..., value ==> ... */
2384 /* op1 = target JavaVM pc, val.i = constant */
2386 var_to_reg_int(s1, src, REG_ITMP1);
2387 if (iptr->val.i == 0) {
2391 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2392 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2395 ICONST(REG_ITMP2, iptr->val.i);
2396 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2398 M_BNEZ(REG_ITMP1, 0);
2400 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2403 case ICMD_IFLT: /* ..., value ==> ... */
2404 /* op1 = target JavaVM pc, val.i = constant */
2406 var_to_reg_int(s1, src, REG_ITMP1);
2407 if (iptr->val.i == 0) {
2411 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2412 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2415 ICONST(REG_ITMP2, iptr->val.i);
2416 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2418 M_BNEZ(REG_ITMP1, 0);
2420 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2423 case ICMD_IFLE: /* ..., value ==> ... */
2424 /* op1 = target JavaVM pc, val.i = constant */
2426 var_to_reg_int(s1, src, REG_ITMP1);
2427 if (iptr->val.i == 0) {
2431 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2432 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2435 ICONST(REG_ITMP2, iptr->val.i);
2436 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2438 M_BNEZ(REG_ITMP1, 0);
2440 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2443 case ICMD_IFNE: /* ..., value ==> ... */
2444 /* op1 = target JavaVM pc, val.i = constant */
2446 var_to_reg_int(s1, src, REG_ITMP1);
2447 if (iptr->val.i == 0) {
2451 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2452 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2455 ICONST(REG_ITMP2, iptr->val.i);
2456 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2458 M_BEQZ(REG_ITMP1, 0);
2460 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2463 case ICMD_IFGT: /* ..., value ==> ... */
2464 /* op1 = target JavaVM pc, val.i = constant */
2466 var_to_reg_int(s1, src, REG_ITMP1);
2467 if (iptr->val.i == 0) {
2471 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2472 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2475 ICONST(REG_ITMP2, iptr->val.i);
2476 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2478 M_BEQZ(REG_ITMP1, 0);
2480 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2483 case ICMD_IFGE: /* ..., value ==> ... */
2484 /* op1 = target JavaVM pc, val.i = constant */
2486 var_to_reg_int(s1, src, REG_ITMP1);
2487 if (iptr->val.i == 0) {
2491 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2492 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2495 ICONST(REG_ITMP2, iptr->val.i);
2496 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2498 M_BEQZ(REG_ITMP1, 0);
2500 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2503 case ICMD_IF_LEQ: /* ..., value ==> ... */
2504 /* op1 = target JavaVM pc, val.l = constant */
2506 var_to_reg_int(s1, src, REG_ITMP1);
2507 if (iptr->val.l == 0) {
2511 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2512 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2515 LCONST(REG_ITMP2, iptr->val.l);
2516 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2518 M_BNEZ(REG_ITMP1, 0);
2520 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2523 case ICMD_IF_LLT: /* ..., value ==> ... */
2524 /* op1 = target JavaVM pc, val.l = constant */
2526 var_to_reg_int(s1, src, REG_ITMP1);
2527 if (iptr->val.l == 0) {
2531 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2532 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2535 LCONST(REG_ITMP2, iptr->val.l);
2536 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2538 M_BNEZ(REG_ITMP1, 0);
2540 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2543 case ICMD_IF_LLE: /* ..., value ==> ... */
2544 /* op1 = target JavaVM pc, val.l = constant */
2546 var_to_reg_int(s1, src, REG_ITMP1);
2547 if (iptr->val.l == 0) {
2551 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2552 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2555 LCONST(REG_ITMP2, iptr->val.l);
2556 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2558 M_BNEZ(REG_ITMP1, 0);
2560 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2563 case ICMD_IF_LNE: /* ..., value ==> ... */
2564 /* op1 = target JavaVM pc, val.l = constant */
2566 var_to_reg_int(s1, src, REG_ITMP1);
2567 if (iptr->val.l == 0) {
2571 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2572 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2575 LCONST(REG_ITMP2, iptr->val.l);
2576 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2578 M_BEQZ(REG_ITMP1, 0);
2580 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2583 case ICMD_IF_LGT: /* ..., value ==> ... */
2584 /* op1 = target JavaVM pc, val.l = constant */
2586 var_to_reg_int(s1, src, REG_ITMP1);
2587 if (iptr->val.l == 0) {
2591 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2592 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2595 LCONST(REG_ITMP2, iptr->val.l);
2596 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2598 M_BEQZ(REG_ITMP1, 0);
2600 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2603 case ICMD_IF_LGE: /* ..., value ==> ... */
2604 /* op1 = target JavaVM pc, val.l = constant */
2606 var_to_reg_int(s1, src, REG_ITMP1);
2607 if (iptr->val.l == 0) {
2611 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2612 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2615 LCONST(REG_ITMP2, iptr->val.l);
2616 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2618 M_BEQZ(REG_ITMP1, 0);
2620 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2623 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2624 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2625 case ICMD_IF_ACMPEQ:
2627 var_to_reg_int(s1, src->prev, REG_ITMP1);
2628 var_to_reg_int(s2, src, REG_ITMP2);
2629 M_CMPEQ(s1, s2, REG_ITMP1);
2630 M_BNEZ(REG_ITMP1, 0);
2631 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2634 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2635 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2636 case ICMD_IF_ACMPNE:
2638 var_to_reg_int(s1, src->prev, REG_ITMP1);
2639 var_to_reg_int(s2, src, REG_ITMP2);
2640 M_CMPEQ(s1, s2, REG_ITMP1);
2641 M_BEQZ(REG_ITMP1, 0);
2642 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2645 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2646 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2648 var_to_reg_int(s1, src->prev, REG_ITMP1);
2649 var_to_reg_int(s2, src, REG_ITMP2);
2650 M_CMPLT(s1, s2, REG_ITMP1);
2651 M_BNEZ(REG_ITMP1, 0);
2652 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2655 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2656 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2658 var_to_reg_int(s1, src->prev, REG_ITMP1);
2659 var_to_reg_int(s2, src, REG_ITMP2);
2660 M_CMPLE(s1, s2, REG_ITMP1);
2661 M_BEQZ(REG_ITMP1, 0);
2662 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2665 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2666 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2668 var_to_reg_int(s1, src->prev, REG_ITMP1);
2669 var_to_reg_int(s2, src, REG_ITMP2);
2670 M_CMPLE(s1, s2, REG_ITMP1);
2671 M_BNEZ(REG_ITMP1, 0);
2672 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2675 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2676 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2678 var_to_reg_int(s1, src->prev, REG_ITMP1);
2679 var_to_reg_int(s2, src, REG_ITMP2);
2680 M_CMPLT(s1, s2, REG_ITMP1);
2681 M_BEQZ(REG_ITMP1, 0);
2682 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2685 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2687 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2690 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2691 /* val.i = constant */
2693 var_to_reg_int(s1, src, REG_ITMP1);
2694 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2696 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2697 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2698 M_CMPEQ(s1, REG_ZERO, d);
2699 store_reg_to_var_int(iptr->dst, d);
2702 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2703 M_CMPEQ(s1, REG_ZERO, d);
2705 store_reg_to_var_int(iptr->dst, d);
2709 M_MOV(s1, REG_ITMP1);
2712 ICONST(d, iptr[1].val.i);
2714 if ((s3 >= 0) && (s3 <= 255)) {
2715 M_CMOVEQ_IMM(s1, s3, d);
2717 ICONST(REG_ITMP2, s3);
2718 M_CMOVEQ(s1, REG_ITMP2, d);
2720 store_reg_to_var_int(iptr->dst, d);
2723 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2724 /* val.i = constant */
2726 var_to_reg_int(s1, src, REG_ITMP1);
2727 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2729 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2730 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2731 M_CMPEQ(s1, REG_ZERO, d);
2732 store_reg_to_var_int(iptr->dst, d);
2735 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2736 M_CMPEQ(s1, REG_ZERO, d);
2738 store_reg_to_var_int(iptr->dst, d);
2742 M_MOV(s1, REG_ITMP1);
2745 ICONST(d, iptr[1].val.i);
2747 if ((s3 >= 0) && (s3 <= 255)) {
2748 M_CMOVNE_IMM(s1, s3, d);
2750 ICONST(REG_ITMP2, s3);
2751 M_CMOVNE(s1, REG_ITMP2, d);
2753 store_reg_to_var_int(iptr->dst, d);
2756 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2757 /* val.i = constant */
2759 var_to_reg_int(s1, src, REG_ITMP1);
2760 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2762 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2763 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2764 M_CMPLT(s1, REG_ZERO, d);
2765 store_reg_to_var_int(iptr->dst, d);
2768 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2769 M_CMPLE(REG_ZERO, s1, d);
2770 store_reg_to_var_int(iptr->dst, d);
2774 M_MOV(s1, REG_ITMP1);
2777 ICONST(d, iptr[1].val.i);
2779 if ((s3 >= 0) && (s3 <= 255)) {
2780 M_CMOVLT_IMM(s1, s3, d);
2782 ICONST(REG_ITMP2, s3);
2783 M_CMOVLT(s1, REG_ITMP2, d);
2785 store_reg_to_var_int(iptr->dst, d);
2788 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2789 /* val.i = constant */
2791 var_to_reg_int(s1, src, REG_ITMP1);
2792 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2794 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2795 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2796 M_CMPLE(REG_ZERO, s1, d);
2797 store_reg_to_var_int(iptr->dst, d);
2800 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2801 M_CMPLT(s1, REG_ZERO, d);
2802 store_reg_to_var_int(iptr->dst, d);
2806 M_MOV(s1, REG_ITMP1);
2809 ICONST(d, iptr[1].val.i);
2811 if ((s3 >= 0) && (s3 <= 255)) {
2812 M_CMOVGE_IMM(s1, s3, d);
2814 ICONST(REG_ITMP2, s3);
2815 M_CMOVGE(s1, REG_ITMP2, d);
2817 store_reg_to_var_int(iptr->dst, d);
2820 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2821 /* val.i = constant */
2823 var_to_reg_int(s1, src, REG_ITMP1);
2824 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2826 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2827 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2828 M_CMPLT(REG_ZERO, s1, d);
2829 store_reg_to_var_int(iptr->dst, d);
2832 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2833 M_CMPLE(s1, REG_ZERO, d);
2834 store_reg_to_var_int(iptr->dst, d);
2838 M_MOV(s1, REG_ITMP1);
2841 ICONST(d, iptr[1].val.i);
2843 if ((s3 >= 0) && (s3 <= 255)) {
2844 M_CMOVGT_IMM(s1, s3, d);
2846 ICONST(REG_ITMP2, s3);
2847 M_CMOVGT(s1, REG_ITMP2, d);
2849 store_reg_to_var_int(iptr->dst, d);
2852 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2853 /* val.i = constant */
2855 var_to_reg_int(s1, src, REG_ITMP1);
2856 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2858 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2859 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2860 M_CMPLE(s1, REG_ZERO, d);
2861 store_reg_to_var_int(iptr->dst, d);
2864 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2865 M_CMPLT(REG_ZERO, s1, d);
2866 store_reg_to_var_int(iptr->dst, d);
2870 M_MOV(s1, REG_ITMP1);
2873 ICONST(d, iptr[1].val.i);
2875 if ((s3 >= 0) && (s3 <= 255)) {
2876 M_CMOVLE_IMM(s1, s3, d);
2878 ICONST(REG_ITMP2, s3);
2879 M_CMOVLE(s1, REG_ITMP2, d);
2881 store_reg_to_var_int(iptr->dst, d);
2885 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2888 var_to_reg_int(s1, src, REG_RESULT);
2889 M_INTMOVE(s1, REG_RESULT);
2890 goto nowperformreturn;
2892 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2894 var_to_reg_int(s1, src, REG_RESULT);
2895 M_INTMOVE(s1, REG_RESULT);
2898 codegen_addpatchref(cd, mcodeptr,
2899 PATCHER_athrow_areturn,
2900 (unresolved_class *) iptr->val.a, 0);
2902 if (opt_showdisassemble)
2905 goto nowperformreturn;
2907 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2910 var_to_reg_flt(s1, src, REG_FRESULT);
2911 M_FLTMOVE(s1, REG_FRESULT);
2912 goto nowperformreturn;
2914 case ICMD_RETURN: /* ... ==> ... */
2920 p = parentargs_base;
2922 /* call trace function */
2925 M_LDA(REG_SP, REG_SP, -3 * 8);
2926 M_AST(REG_RA, REG_SP, 0 * 8);
2927 M_LST(REG_RESULT, REG_SP, 1 * 8);
2928 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2930 disp = dseg_addaddress(cd, m);
2931 M_ALD(rd->argintregs[0], REG_PV, disp);
2932 M_MOV(REG_RESULT, rd->argintregs[1]);
2933 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2934 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2936 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2937 M_ALD(REG_PV, REG_PV, disp);
2938 M_JSR(REG_RA, REG_PV);
2939 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2940 M_LDA(REG_PV, REG_RA, -disp);
2942 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2943 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2944 M_ALD(REG_RA, REG_SP, 0 * 8);
2945 M_LDA(REG_SP, REG_SP, 3 * 8);
2948 #if defined(USE_THREADS)
2949 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2950 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2952 switch (iptr->opc) {
2956 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2960 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2964 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2965 M_ALD(REG_PV, REG_PV, disp);
2966 M_JSR(REG_RA, REG_PV);
2967 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2968 M_LDA(REG_PV, REG_RA, disp);
2970 switch (iptr->opc) {
2974 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2978 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2984 /* restore return address */
2986 if (!m->isleafmethod) {
2987 p--; M_LLD(REG_RA, REG_SP, p * 8);
2990 /* restore saved registers */
2992 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2993 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2995 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2996 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2999 /* deallocate stack */
3001 if (parentargs_base) {
3002 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
3005 M_RET(REG_ZERO, REG_RA);
3011 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3016 tptr = (void **) iptr->target;
3018 s4ptr = iptr->val.a;
3019 l = s4ptr[1]; /* low */
3020 i = s4ptr[2]; /* high */
3022 var_to_reg_int(s1, src, REG_ITMP1);
3024 M_INTMOVE(s1, REG_ITMP1);
3025 } else if (l <= 32768) {
3026 M_LDA(REG_ITMP1, s1, -l);
3028 ICONST(REG_ITMP2, l);
3029 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3036 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3038 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3039 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3041 M_BEQZ(REG_ITMP2, 0);
3042 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3044 /* build jump table top down and use address of lowest entry */
3046 /* s4ptr += 3 + i; */
3050 dseg_addtarget(cd, (basicblock *) tptr[0]);
3055 /* length of dataseg after last dseg_addtarget is used by load */
3057 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3058 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3059 M_JMP(REG_ZERO, REG_ITMP2);
3064 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3066 s4 i, l, val, *s4ptr;
3069 tptr = (void **) iptr->target;
3071 s4ptr = iptr->val.a;
3072 l = s4ptr[0]; /* default */
3073 i = s4ptr[1]; /* count */
3075 MCODECHECK((i<<2)+8);
3076 var_to_reg_int(s1, src, REG_ITMP1);
3082 if ((val >= 0) && (val <= 255)) {
3083 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3085 if ((val >= -32768) && (val <= 32767)) {
3086 M_LDA(REG_ITMP2, REG_ZERO, val);
3088 disp = dseg_adds4(cd, val);
3089 M_ILD(REG_ITMP2, REG_PV, disp);
3091 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3093 M_BNEZ(REG_ITMP2, 0);
3094 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3099 tptr = (void **) iptr->target;
3100 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3107 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3108 /* op1 = arg count val.a = builtintable entry */
3114 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3115 /* op1 = arg count, val.a = method pointer */
3117 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3118 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3119 case ICMD_INVOKEINTERFACE:
3124 unresolved_method *um = iptr->target;
3125 md = um->methodref->parseddesc.md;
3127 md = lm->parseddesc;
3131 s3 = md->paramcount;
3133 MCODECHECK((s3 << 1) + 64);
3135 /* copy arguments to registers or stack location */
3137 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3138 if (src->varkind == ARGVAR)
3140 if (IS_INT_LNG_TYPE(src->type)) {
3141 if (!md->params[s3].inmemory) {
3142 s1 = rd->argintregs[md->params[s3].regoff];
3143 var_to_reg_int(d, src, s1);
3146 var_to_reg_int(d, src, REG_ITMP1);
3147 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3151 if (!md->params[s3].inmemory) {
3152 s1 = rd->argfltregs[md->params[s3].regoff];
3153 var_to_reg_flt(d, src, s1);
3156 var_to_reg_flt(d, src, REG_FTMP1);
3157 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3162 switch (iptr->opc) {
3164 disp = dseg_addaddress(cd, bte->fp);
3165 d = md->returntype.type;
3167 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3168 M_JSR(REG_RA, REG_PV);
3169 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3170 M_LDA(REG_PV, REG_RA, -disp);
3172 /* if op1 == true, we need to check for an exception */
3174 if (iptr->op1 == true) {
3175 M_BEQZ(REG_RESULT, 0);
3176 codegen_addxexceptionrefs(cd, mcodeptr);
3180 case ICMD_INVOKESPECIAL:
3181 M_BEQZ(rd->argintregs[0], 0);
3182 codegen_addxnullrefs(cd, mcodeptr);
3185 case ICMD_INVOKESTATIC:
3187 unresolved_method *um = iptr->target;
3189 disp = dseg_addaddress(cd, NULL);
3191 codegen_addpatchref(cd, mcodeptr,
3192 PATCHER_invokestatic_special, um, disp);
3194 if (opt_showdisassemble)
3197 d = um->methodref->parseddesc.md->returntype.type;
3200 disp = dseg_addaddress(cd, lm->stubroutine);
3201 d = lm->parseddesc->returntype.type;
3204 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3205 M_JSR(REG_RA, REG_PV);
3206 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3207 M_LDA(REG_PV, REG_RA, -disp);
3210 case ICMD_INVOKEVIRTUAL:
3211 gen_nullptr_check(rd->argintregs[0]);
3214 unresolved_method *um = iptr->target;
3216 codegen_addpatchref(cd, mcodeptr,
3217 PATCHER_invokevirtual, um, 0);
3219 if (opt_showdisassemble)
3223 d = um->methodref->parseddesc.md->returntype.type;
3226 s1 = OFFSET(vftbl_t, table[0]) +
3227 sizeof(methodptr) * lm->vftblindex;
3228 d = lm->parseddesc->returntype.type;
3231 M_ALD(REG_METHODPTR, rd->argintregs[0],
3232 OFFSET(java_objectheader, vftbl));
3233 M_ALD(REG_PV, REG_METHODPTR, s1);
3234 M_JSR(REG_RA, REG_PV);
3235 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3236 M_LDA(REG_PV, REG_RA, -disp);
3239 case ICMD_INVOKEINTERFACE:
3240 gen_nullptr_check(rd->argintregs[0]);
3243 unresolved_method *um = iptr->target;
3245 codegen_addpatchref(cd, mcodeptr,
3246 PATCHER_invokeinterface, um, 0);
3248 if (opt_showdisassemble)
3253 d = um->methodref->parseddesc.md->returntype.type;
3256 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3257 sizeof(methodptr*) * lm->class->index;
3259 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3261 d = lm->parseddesc->returntype.type;
3264 M_ALD(REG_METHODPTR, rd->argintregs[0],
3265 OFFSET(java_objectheader, vftbl));
3266 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3267 M_ALD(REG_PV, REG_METHODPTR, s2);
3268 M_JSR(REG_RA, REG_PV);
3269 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3270 M_LDA(REG_PV, REG_RA, -disp);
3274 /* d contains return type */
3276 if (d != TYPE_VOID) {
3277 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3278 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3279 M_INTMOVE(REG_RESULT, s1);
3280 store_reg_to_var_int(iptr->dst, s1);
3282 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3283 M_FLTMOVE(REG_FRESULT, s1);
3284 store_reg_to_var_flt(iptr->dst, s1);
3290 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3292 /* op1: 0 == array, 1 == class */
3293 /* val.a: (classinfo*) superclass */
3295 /* superclass is an interface:
3297 * OK if ((sub == NULL) ||
3298 * (sub->vftbl->interfacetablelength > super->index) &&
3299 * (sub->vftbl->interfacetable[-super->index] != NULL));
3301 * superclass is a class:
3303 * OK if ((sub == NULL) || (0
3304 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3305 * super->vftbl->diffval));
3308 if (iptr->op1 == 1) {
3309 /* object type cast-check */
3312 vftbl_t *supervftbl;
3315 super = (classinfo *) iptr->val.a;
3322 superindex = super->index;
3323 supervftbl = super->vftbl;
3326 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3327 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3329 var_to_reg_int(s1, src, REG_ITMP1);
3331 /* calculate interface checkcast code size */
3335 s2 += opt_showdisassemble ? 1 : 0;
3337 /* calculate class checkcast code size */
3339 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3341 s3 += opt_showdisassemble ? 1 : 0;
3343 /* if class is not resolved, check which code to call */
3346 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3348 disp = dseg_adds4(cd, 0); /* super->flags */
3350 codegen_addpatchref(cd, mcodeptr,
3351 PATCHER_checkcast_instanceof_flags,
3352 (constant_classref *) iptr->target,
3355 if (opt_showdisassemble)
3358 M_ILD(REG_ITMP2, REG_PV, disp);
3359 disp = dseg_adds4(cd, ACC_INTERFACE);
3360 M_ILD(REG_ITMP3, REG_PV, disp);
3361 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3362 M_BEQZ(REG_ITMP2, s2 + 1);
3365 /* interface checkcast code */
3367 if (!super || (super->flags & ACC_INTERFACE)) {
3372 codegen_addpatchref(cd, mcodeptr,
3373 PATCHER_checkcast_instanceof_interface,
3374 (constant_classref *) iptr->target,
3377 if (opt_showdisassemble)
3381 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3382 M_ILD(REG_ITMP3, REG_ITMP2,
3383 OFFSET(vftbl_t, interfacetablelength));
3384 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3385 M_BLEZ(REG_ITMP3, 0);
3386 codegen_addxcastrefs(cd, mcodeptr);
3387 M_ALD(REG_ITMP3, REG_ITMP2,
3388 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3389 superindex * sizeof(methodptr*)));
3390 M_BEQZ(REG_ITMP3, 0);
3391 codegen_addxcastrefs(cd, mcodeptr);
3397 /* class checkcast code */
3399 if (!super || !(super->flags & ACC_INTERFACE)) {
3400 disp = dseg_addaddress(cd, supervftbl);
3406 codegen_addpatchref(cd, mcodeptr,
3407 PATCHER_checkcast_instanceof_class,
3408 (constant_classref *) iptr->target,
3411 if (opt_showdisassemble)
3415 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3416 M_ALD(REG_ITMP3, REG_PV, disp);
3417 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3418 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3420 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3421 /* if (s1 != REG_ITMP1) { */
3422 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3423 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3424 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3425 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3427 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3430 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3431 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3432 M_ALD(REG_ITMP3, REG_PV, disp);
3433 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3434 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3435 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3438 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3439 M_BEQZ(REG_ITMP3, 0);
3440 codegen_addxcastrefs(cd, mcodeptr);
3442 d = reg_of_var(rd, iptr->dst, s1);
3445 /* array type cast-check */
3447 var_to_reg_int(s1, src, rd->argintregs[0]);
3448 M_INTMOVE(s1, rd->argintregs[0]);
3450 disp = dseg_addaddress(cd, iptr->val.a);
3452 if (iptr->val.a == NULL) {
3453 codegen_addpatchref(cd, mcodeptr,
3454 PATCHER_builtin_arraycheckcast,
3455 (constant_classref *) iptr->target,
3458 if (opt_showdisassemble)
3462 M_ALD(rd->argintregs[1], REG_PV, disp);
3463 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3464 M_ALD(REG_PV, REG_PV, disp);
3465 M_JSR(REG_RA, REG_PV);
3466 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3467 M_LDA(REG_PV, REG_RA, -disp);
3469 M_BEQZ(REG_RESULT, 0);
3470 codegen_addxcastrefs(cd, mcodeptr);
3472 var_to_reg_int(s1, src, REG_ITMP1);
3473 d = reg_of_var(rd, iptr->dst, s1);
3476 store_reg_to_var_int(iptr->dst, d);
3479 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3481 /* op1: 0 == array, 1 == class */
3482 /* val.a: (classinfo*) superclass */
3484 /* superclass is an interface:
3486 * return (sub != NULL) &&
3487 * (sub->vftbl->interfacetablelength > super->index) &&
3488 * (sub->vftbl->interfacetable[-super->index] != NULL);
3490 * superclass is a class:
3492 * return ((sub != NULL) && (0
3493 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3494 * super->vftbl->diffvall));
3499 vftbl_t *supervftbl;
3502 super = (classinfo *) iptr->val.a;
3509 superindex = super->index;
3510 supervftbl = super->vftbl;
3513 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3514 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3516 var_to_reg_int(s1, src, REG_ITMP1);
3517 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3519 M_MOV(s1, REG_ITMP1);
3523 /* calculate interface instanceof code size */
3527 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3529 /* calculate class instanceof code size */
3533 s3 += (opt_showdisassemble ? 1 : 0);
3535 /* if class is not resolved, check which code to call */
3539 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3541 disp = dseg_adds4(cd, 0); /* super->flags */
3543 codegen_addpatchref(cd, mcodeptr,
3544 PATCHER_checkcast_instanceof_flags,
3545 (constant_classref *) iptr->target, disp);
3547 if (opt_showdisassemble)
3550 M_ILD(REG_ITMP3, REG_PV, disp);
3552 disp = dseg_adds4(cd, ACC_INTERFACE);
3553 M_ILD(REG_ITMP2, REG_PV, disp);
3554 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3555 M_BEQZ(REG_ITMP3, s2 + 1);
3558 /* interface instanceof code */
3560 if (!super || (super->flags & ACC_INTERFACE)) {
3566 /* If d == REG_ITMP2, then it's destroyed in check code */
3571 codegen_addpatchref(cd, mcodeptr,
3572 PATCHER_checkcast_instanceof_interface,
3573 (constant_classref *) iptr->target, 0);
3575 if (opt_showdisassemble)
3579 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3580 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3581 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3582 M_BLEZ(REG_ITMP3, 2);
3583 M_ALD(REG_ITMP1, REG_ITMP1,
3584 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3585 superindex * sizeof(methodptr*)));
3586 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3592 /* class instanceof code */
3594 if (!super || !(super->flags & ACC_INTERFACE)) {
3595 disp = dseg_addaddress(cd, supervftbl);
3602 codegen_addpatchref(cd, mcodeptr,
3603 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 *) 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 *) mcodeptr - cd->mcodebase);
3622 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3623 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3625 store_reg_to_var_int(iptr->dst, d);
3629 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3630 /* op1 = dimension, val.a = array descriptor */
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 var_to_reg_int(s2, 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? */
3652 disp = dseg_addaddress(cd, 0);
3654 codegen_addpatchref(cd, mcodeptr,
3655 (functionptr) iptr->target, iptr->val.a,
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, (void *) BUILTIN_multianewarray);
3674 M_ALD(REG_PV, REG_PV, disp);
3675 M_JSR(REG_RA, REG_PV);
3676 disp = (s4) ((u1 *) 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_addxexceptionrefs(cd, mcodeptr);
3684 d = reg_of_var(rd, iptr->dst, REG_RESULT);
3685 M_INTMOVE(REG_RESULT, d);
3686 store_reg_to_var_int(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;
3707 if ((src->varkind != STACKVAR)) {
3709 if (IS_FLT_DBL_TYPE(s2)) {
3710 var_to_reg_flt(s1, src, REG_FTMP1);
3711 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3712 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3715 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3719 var_to_reg_int(s1, src, REG_ITMP1);
3720 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3721 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3724 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3730 } /* if (bptr -> flags >= BBREACHED) */
3731 } /* for basic block */
3733 codegen_createlinenumbertable(cd);
3737 s4 *xcodeptr = NULL;
3740 /* generate ArithmeticException stubs */
3742 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3743 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3745 (u1 *) mcodeptr - cd->mcodebase);
3749 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3751 if (xcodeptr != NULL) {
3752 disp = xcodeptr - mcodeptr - 1;
3756 xcodeptr = mcodeptr;
3758 M_MOV(REG_PV, rd->argintregs[0]);
3759 M_MOV(REG_SP, rd->argintregs[1]);
3760 M_ALD(rd->argintregs[2],
3761 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3762 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3764 M_LDA(REG_SP, REG_SP, -1 * 8);
3765 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3767 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3768 M_ALD(REG_PV, REG_PV, disp);
3769 M_JSR(REG_RA, REG_PV);
3770 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3771 M_LDA(REG_PV, REG_RA, -disp);
3773 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3775 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3776 M_LDA(REG_SP, REG_SP, 1 * 8);
3778 disp = dseg_addaddress(cd, asm_handle_exception);
3779 M_ALD(REG_ITMP3, REG_PV, disp);
3780 M_JMP(REG_ZERO, REG_ITMP3);
3784 /* generate ArrayIndexOutOfBoundsException stubs */
3788 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3789 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3791 (u1*) mcodeptr - cd->mcodebase);
3795 /* move index register into REG_ITMP1 */
3797 M_MOV(bref->reg, REG_ITMP1);
3798 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3800 if (xcodeptr != NULL) {
3801 disp = xcodeptr - mcodeptr - 1;
3805 xcodeptr = mcodeptr;
3807 M_MOV(REG_PV, rd->argintregs[0]);
3808 M_MOV(REG_SP, rd->argintregs[1]);
3810 if (m->isleafmethod)
3811 M_MOV(REG_RA, rd->argintregs[2]);
3813 M_ALD(rd->argintregs[2],
3814 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3816 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3817 M_MOV(REG_ITMP1, rd->argintregs[4]);
3819 M_LDA(REG_SP, REG_SP, -2 * 8);
3820 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3822 if (m->isleafmethod)
3823 M_AST(REG_RA, REG_SP, 1 * 8);
3825 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3826 M_ALD(REG_PV, REG_PV, disp);
3827 M_JSR(REG_RA, REG_PV);
3828 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3829 M_LDA(REG_PV, REG_RA, -disp);
3831 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3833 if (m->isleafmethod)
3834 M_ALD(REG_RA, REG_SP, 1 * 8);
3836 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3837 M_LDA(REG_SP, REG_SP, 2 * 8);
3839 disp = dseg_addaddress(cd, asm_handle_exception);
3840 M_ALD(REG_ITMP3, REG_PV, disp);
3841 M_JMP(REG_ZERO, REG_ITMP3);
3845 /* generate ArrayStoreException stubs */
3849 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3850 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3852 (u1 *) mcodeptr - cd->mcodebase);
3856 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3858 if (xcodeptr != NULL) {
3859 disp = xcodeptr - mcodeptr - 1;
3863 xcodeptr = mcodeptr;
3865 M_MOV(REG_PV, rd->argintregs[0]);
3866 M_MOV(REG_SP, rd->argintregs[1]);
3867 M_ALD(rd->argintregs[2],
3868 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3869 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3871 M_LDA(REG_SP, REG_SP, -1 * 8);
3872 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3874 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3875 M_ALD(REG_PV, REG_PV, disp);
3876 M_JSR(REG_RA, REG_PV);
3877 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3878 M_LDA(REG_PV, REG_RA, -disp);
3880 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3882 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3883 M_LDA(REG_SP, REG_SP, 1 * 8);
3885 disp = dseg_addaddress(cd, asm_handle_exception);
3886 M_ALD(REG_ITMP3, REG_PV, disp);
3887 M_JMP(REG_ZERO, REG_ITMP3);
3891 /* generate ClassCastException stubs */
3895 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3896 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3898 (u1 *) mcodeptr - cd->mcodebase);
3902 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3904 if (xcodeptr != NULL) {
3905 disp = xcodeptr - mcodeptr - 1;
3909 xcodeptr = mcodeptr;
3911 M_MOV(REG_PV, rd->argintregs[0]);
3912 M_MOV(REG_SP, rd->argintregs[1]);
3914 if (m->isleafmethod)
3915 M_MOV(REG_RA, rd->argintregs[2]);
3917 M_ALD(rd->argintregs[2],
3918 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3920 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3922 M_LDA(REG_SP, REG_SP, -2 * 8);
3923 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3925 if (m->isleafmethod)
3926 M_AST(REG_RA, REG_SP, 1 * 8);
3928 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3929 M_ALD(REG_PV, REG_PV, disp);
3930 M_JSR(REG_RA, REG_PV);
3931 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3932 M_LDA(REG_PV, REG_RA, -disp);
3934 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3936 if (m->isleafmethod)
3937 M_ALD(REG_RA, REG_SP, 1 * 8);
3939 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3940 M_LDA(REG_SP, REG_SP, 2 * 8);
3942 disp = dseg_addaddress(cd, asm_handle_exception);
3943 M_ALD(REG_ITMP3, REG_PV, disp);
3944 M_JMP(REG_ZERO, REG_ITMP3);
3948 /* generate NullPointerException stubs */
3952 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3953 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3955 (u1 *) mcodeptr - cd->mcodebase);
3959 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3961 if (xcodeptr != NULL) {
3962 disp = xcodeptr - mcodeptr - 1;
3966 xcodeptr = mcodeptr;
3968 M_MOV(REG_PV, rd->argintregs[0]);
3969 M_MOV(REG_SP, rd->argintregs[1]);
3971 if (m->isleafmethod)
3972 M_MOV(REG_RA, rd->argintregs[2]);
3974 M_ALD(rd->argintregs[2],
3975 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3977 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3979 M_LDA(REG_SP, REG_SP, -2 * 8);
3980 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3982 if (m->isleafmethod)
3983 M_AST(REG_RA, REG_SP, 1 * 8);
3985 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
3986 M_ALD(REG_PV, REG_PV, disp);
3987 M_JSR(REG_RA, REG_PV);
3988 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3989 M_LDA(REG_PV, REG_RA, -disp);
3991 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3993 if (m->isleafmethod)
3994 M_ALD(REG_RA, REG_SP, 1 * 8);
3996 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3997 M_LDA(REG_SP, REG_SP, 2 * 8);
3999 disp = dseg_addaddress(cd, asm_handle_exception);
4000 M_ALD(REG_ITMP3, REG_PV, disp);
4001 M_JMP(REG_ZERO, REG_ITMP3);
4005 /* generate exception check stubs */
4009 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4010 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4012 (u1 *) mcodeptr - cd->mcodebase);
4016 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4018 if (xcodeptr != NULL) {
4019 disp = xcodeptr - mcodeptr - 1;
4023 xcodeptr = mcodeptr;
4025 M_MOV(REG_PV, rd->argintregs[0]);
4026 M_MOV(REG_SP, rd->argintregs[1]);
4027 M_ALD(rd->argintregs[2],
4028 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4029 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4031 M_LDA(REG_SP, REG_SP, -1 * 8);
4032 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4034 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4035 M_ALD(REG_PV, REG_PV, disp);
4036 M_JSR(REG_RA, REG_PV);
4037 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4038 M_LDA(REG_PV, REG_RA, -disp);
4040 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4042 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4043 M_LDA(REG_SP, REG_SP, 1 * 8);
4045 disp = dseg_addaddress(cd, asm_handle_exception);
4046 M_ALD(REG_ITMP3, REG_PV, disp);
4047 M_JMP(REG_ZERO, REG_ITMP3);
4051 /* generate patcher stub call code */
4058 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4059 /* check code segment size */
4063 /* Get machine code which is patched back in later. The call is */
4064 /* 1 instruction word long. */
4066 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4069 /* patch in the call to call the following code (done at compile */
4072 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4073 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4075 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4077 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4079 /* create stack frame */
4081 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4083 /* move return address onto stack */
4085 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4087 /* move pointer to java_objectheader onto stack */
4089 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4090 /* create a virtual java_objectheader */
4092 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4093 disp = dseg_addaddress(cd, NULL); /* vftbl */
4095 M_LDA(REG_ITMP3, REG_PV, disp);
4096 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4101 /* move machine code onto stack */
4103 disp = dseg_adds4(cd, mcode);
4104 M_ILD(REG_ITMP3, REG_PV, disp);
4105 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4107 /* move class/method/field reference onto stack */
4109 disp = dseg_addaddress(cd, pref->ref);
4110 M_ALD(REG_ITMP3, REG_PV, disp);
4111 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4113 /* move data segment displacement onto stack */
4115 disp = dseg_adds4(cd, pref->disp);
4116 M_ILD(REG_ITMP3, REG_PV, disp);
4117 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4119 /* move patcher function pointer onto stack */
4121 disp = dseg_addaddress(cd, pref->patcher);
4122 M_ALD(REG_ITMP3, REG_PV, disp);
4123 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4125 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4126 M_ALD(REG_ITMP3, REG_PV, disp);
4127 M_JMP(REG_ZERO, REG_ITMP3);
4132 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4134 /* everything's ok */
4140 /* createcompilerstub **********************************************************
4142 Creates a stub routine which calls the compiler.
4144 *******************************************************************************/
4146 #define COMPSTUBSIZE 3
4148 functionptr createcompilerstub(methodinfo *m)
4150 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4151 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4153 /* code for the stub */
4154 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4155 M_JMP(0, REG_PV); /* jump to the compiler, return address
4156 in reg 0 is used as method pointer */
4157 s[1] = (ptrint) m; /* literals to be adressed */
4158 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4160 #if defined(STATISTICS)
4162 count_cstub_len += COMPSTUBSIZE * 8;
4165 return (functionptr) s;
4169 /* createnativestub ************************************************************
4171 Creates a stub routine which calls a native method.
4173 *******************************************************************************/
4175 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4176 registerdata *rd, methoddesc *nmd)
4178 s4 *mcodeptr; /* code generation pointer */
4179 s4 stackframesize; /* size of stackframe if needed */
4182 s4 i, j; /* count variables */
4185 s4 funcdisp; /* displacement of the function */
4187 /* initialize variables */
4190 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4193 /* calculate stack frame size */
4196 1 + /* return address */
4197 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4198 sizeof(localref_table) / SIZEOF_VOID_P +
4199 1 + /* methodinfo for call trace */
4200 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4204 /* create method header */
4206 (void) dseg_addaddress(cd, m); /* MethodPointer */
4207 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4208 (void) dseg_adds4(cd, 0); /* IsSync */
4209 (void) dseg_adds4(cd, 0); /* IsLeaf */
4210 (void) dseg_adds4(cd, 0); /* IntSave */
4211 (void) dseg_adds4(cd, 0); /* FltSave */
4212 (void) dseg_addlinenumbertablesize(cd);
4213 (void) dseg_adds4(cd, 0); /* ExTableSize */
4216 /* initialize mcode variables */
4218 mcodeptr = (s4 *) cd->mcodebase;
4219 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4222 /* generate stub code */
4224 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4225 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4228 /* call trace function */
4231 /* save integer argument registers */
4233 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4234 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4235 M_LST(rd->argintregs[i], REG_SP, j * 8);
4240 /* save and copy float arguments into integer registers */
4242 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4243 t = md->paramtypes[i].type;
4245 if (IS_FLT_DBL_TYPE(t)) {
4246 if (IS_2_WORD_TYPE(t)) {
4247 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4248 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4250 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4251 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4257 disp = dseg_addaddress(cd, m);
4258 M_ALD(REG_ITMP1, REG_PV, disp);
4259 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4260 disp = dseg_addaddress(cd, builtin_trace_args);
4261 M_ALD(REG_PV, REG_PV, disp);
4262 M_JSR(REG_RA, REG_PV);
4263 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4264 M_LDA(REG_PV, REG_RA, -disp);
4266 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4267 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4268 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4273 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4274 t = md->paramtypes[i].type;
4276 if (IS_FLT_DBL_TYPE(t)) {
4277 if (IS_2_WORD_TYPE(t)) {
4278 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4280 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4287 /* get function address (this must happen before the stackframeinfo) */
4289 funcdisp = dseg_addaddress(cd, f);
4291 #if !defined(ENABLE_STATICVM)
4293 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4295 if (opt_showdisassemble)
4300 /* save integer and float argument registers */
4302 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4303 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4304 M_LST(rd->argintregs[i], REG_SP, j * 8);
4309 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4310 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4311 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4316 /* prepare data structures for native function call */
4318 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4319 M_MOV(REG_PV, rd->argintregs[1]);
4320 M_LDA(rd->argintregs[2], REG_SP, stackframesize * 8);
4321 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4322 disp = dseg_addaddress(cd, codegen_start_native_call);
4323 M_ALD(REG_PV, REG_PV, disp);
4324 M_JSR(REG_RA, REG_PV);
4325 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4326 M_LDA(REG_PV, REG_RA, -disp);
4328 /* restore integer and float argument registers */
4330 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4331 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4332 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4337 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4338 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4339 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4344 /* copy or spill arguments to new locations */
4346 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4347 t = md->paramtypes[i].type;
4349 if (IS_INT_LNG_TYPE(t)) {
4350 if (!md->params[i].inmemory) {
4351 s1 = rd->argintregs[md->params[i].regoff];
4353 if (!nmd->params[j].inmemory) {
4354 s2 = rd->argintregs[nmd->params[j].regoff];
4358 s2 = nmd->params[j].regoff;
4359 M_LST(s1, REG_SP, s2 * 8);
4363 s1 = md->params[i].regoff + stackframesize;
4364 s2 = nmd->params[j].regoff;
4365 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4366 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4370 if (!md->params[i].inmemory) {
4371 s1 = rd->argfltregs[md->params[i].regoff];
4373 if (!nmd->params[j].inmemory) {
4374 s2 = rd->argfltregs[nmd->params[j].regoff];
4378 s2 = nmd->params[j].regoff;
4379 if (IS_2_WORD_TYPE(t))
4380 M_DST(s1, REG_SP, s2 * 8);
4382 M_FST(s1, REG_SP, s2 * 8);
4386 s1 = md->params[i].regoff + stackframesize;
4387 s2 = nmd->params[j].regoff;
4388 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4389 if (IS_2_WORD_TYPE(t))
4390 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4392 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4397 /* put class into second argument register */
4399 if (m->flags & ACC_STATIC) {
4400 disp = dseg_addaddress(cd, m->class);
4401 M_ALD(rd->argintregs[1], REG_PV, disp);
4404 /* put env into first argument register */
4406 disp = dseg_addaddress(cd, &env);
4407 M_ALD(rd->argintregs[0], REG_PV, disp);
4409 /* do the native function call */
4411 M_ALD(REG_PV, REG_PV, funcdisp);
4412 M_JSR(REG_RA, REG_PV); /* call native method */
4413 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4414 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4416 /* save return value */
4418 if (IS_INT_LNG_TYPE(md->returntype.type))
4419 M_LST(REG_RESULT, REG_SP, 0 * 8);
4421 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4423 /* remove native stackframe info */
4425 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4426 disp = dseg_addaddress(cd, codegen_finish_native_call);
4427 M_ALD(REG_PV, REG_PV, disp);
4428 M_JSR(REG_RA, REG_PV);
4429 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4430 M_LDA(REG_PV, REG_RA, -disp);
4432 /* call finished trace */
4435 /* just restore the value we need, don't care about the other */
4437 if (IS_INT_LNG_TYPE(md->returntype.type))
4438 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4440 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4442 disp = dseg_addaddress(cd, m);
4443 M_ALD(rd->argintregs[0], REG_PV, disp);
4445 M_MOV(REG_RESULT, rd->argintregs[1]);
4446 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4447 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4449 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4450 M_ALD(REG_PV, REG_PV, disp);
4451 M_JSR(REG_RA, REG_PV);
4452 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4453 M_LDA(REG_PV, REG_RA, -disp);
4456 /* check for exception */
4458 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4459 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4460 M_ALD(REG_PV, REG_PV, disp);
4461 M_JSR(REG_RA, REG_PV);
4462 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4463 M_LDA(REG_PV, REG_RA, -disp);
4464 M_MOV(REG_RESULT, REG_ITMP3);
4466 disp = dseg_addaddress(cd, &_exceptionptr);
4467 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4469 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4471 /* restore return value */
4473 if (IS_INT_LNG_TYPE(md->returntype.type))
4474 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4476 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4478 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4480 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4481 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4482 M_RET(REG_ZERO, REG_RA); /* return to caller */
4484 /* handle exception */
4486 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4488 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4489 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4491 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4493 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4494 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4495 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4498 /* process patcher calls **************************************************/
4506 /* there can only be one <clinit> ref entry */
4507 pref = cd->patchrefs;
4509 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4510 /* Get machine code which is patched back in later. The call is */
4511 /* 1 instruction word long. */
4513 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4514 mcode = (u4) *xcodeptr;
4516 /* patch in the call to call the following code (done at compile */
4519 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4520 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4522 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4524 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4526 /* create stack frame */
4528 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4530 /* move return address onto stack */
4532 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4534 /* move pointer to java_objectheader onto stack */
4536 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4537 /* create a virtual java_objectheader */
4539 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4540 disp = dseg_addaddress(cd, NULL); /* vftbl */
4542 M_LDA(REG_ITMP3, REG_PV, disp);
4543 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4545 M_AST(REG_ZERO, REG_SP, 4 * 8);
4548 /* move machine code onto stack */
4550 disp = dseg_adds4(cd, mcode);
4551 M_ILD(REG_ITMP3, REG_PV, disp);
4552 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4554 /* move class/method/field reference onto stack */
4556 disp = dseg_addaddress(cd, pref->ref);
4557 M_ALD(REG_ITMP3, REG_PV, disp);
4558 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4560 /* move data segment displacement onto stack */
4562 disp = dseg_adds4(cd, pref->disp);
4563 M_ILD(REG_ITMP3, REG_PV, disp);
4564 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4566 /* move patcher function pointer onto stack */
4568 disp = dseg_addaddress(cd, pref->patcher);
4569 M_ALD(REG_ITMP3, REG_PV, disp);
4570 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4572 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4573 M_ALD(REG_ITMP3, REG_PV, disp);
4574 M_JMP(REG_ZERO, REG_ITMP3);
4578 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4580 return m->entrypoint;
4585 * These are local overrides for various environment variables in Emacs.
4586 * Please do not remove this and leave it at the end of the file, where
4587 * Emacs will automagically detect them.
4588 * ---------------------------------------------------------------------
4591 * indent-tabs-mode: t