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 3425 2005-10-12 15:33:35Z 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 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
82 s4 len, s1, s2, s3, d, disp;
92 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
93 builtintable_entry *bte;
96 /* prevent compiler warnings */
107 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
109 /* space to save used callee saved registers */
111 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
112 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
114 parentargs_base = rd->memuse + savedregs_num;
116 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
118 if (checksync && (m->flags & ACC_SYNCHRONIZED))
123 /* create method header */
125 (void) dseg_addaddress(cd, m); /* MethodPointer */
126 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
128 #if defined(USE_THREADS)
130 /* IsSync contains the offset relative to the stack pointer for the
131 argument of monitor_exit used in the exception handler. Since the
132 offset could be zero and give a wrong meaning of the flag it is
136 if (checksync && (m->flags & ACC_SYNCHRONIZED))
137 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
142 (void) dseg_adds4(cd, 0); /* IsSync */
144 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
145 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */
146 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */
148 dseg_addlinenumbertablesize(cd);
150 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
152 /* create exception table */
154 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
155 dseg_addtarget(cd, ex->start);
156 dseg_addtarget(cd, ex->end);
157 dseg_addtarget(cd, ex->handler);
158 (void) dseg_addaddress(cd, ex->catchtype.cls);
161 /* initialize mcode variables */
163 mcodeptr = (s4 *) cd->mcodebase;
164 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
165 MCODECHECK(128 + m->paramcount);
167 /* create stack frame (if necessary) */
169 if (parentargs_base) {
170 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
173 /* save return address and used callee saved registers */
176 if (!m->isleafmethod) {
177 p--; M_AST(REG_RA, REG_SP, p * 8);
179 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
180 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
182 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
183 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
186 /* take arguments out of register or stack frame */
190 for (p = 0, l = 0; p < md->paramcount; p++) {
191 t = md->paramtypes[p].type;
192 var = &(rd->locals[l][t]);
194 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
198 s1 = md->params[p].regoff;
199 if (IS_INT_LNG_TYPE(t)) { /* integer args */
200 if (!md->params[p].inmemory) { /* register arguments */
201 s2 = rd->argintregs[s1];
202 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
203 M_INTMOVE(s2, var->regoff);
205 } else { /* reg arg -> spilled */
206 M_LST(s2, REG_SP, var->regoff * 8);
209 } else { /* stack arguments */
210 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
211 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
213 } else { /* stack arg -> spilled */
214 var->regoff = parentargs_base + s1;
218 } else { /* floating args */
219 if (!md->params[p].inmemory) { /* register arguments */
220 s2 = rd->argfltregs[s1];
221 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
222 M_FLTMOVE(s2, var->regoff);
224 } else { /* reg arg -> spilled */
225 M_DST(s2, REG_SP, var->regoff * 8);
228 } else { /* stack arguments */
229 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
230 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
232 } else { /* stack-arg -> spilled */
233 var->regoff = parentargs_base + s1;
239 /* call monitorenter function */
241 #if defined(USE_THREADS)
242 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
243 /* stack offset for monitor argument */
248 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
250 for (p = 0; p < INT_ARG_CNT; p++)
251 M_LST(rd->argintregs[p], REG_SP, p * 8);
253 for (p = 0; p < FLT_ARG_CNT; p++)
254 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
256 s1 += INT_ARG_CNT + FLT_ARG_CNT;
259 /* decide which monitor enter function to call */
261 if (m->flags & ACC_STATIC) {
262 disp = dseg_addaddress(cd, m->class);
263 M_ALD(REG_ITMP1, REG_PV, disp);
264 M_AST(REG_ITMP1, REG_SP, s1 * 8);
265 M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
266 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
267 M_ALD(REG_PV, REG_PV, disp);
268 M_JSR(REG_RA, REG_PV);
269 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
270 M_LDA(REG_PV, REG_RA, disp);
273 M_BEQZ(rd->argintregs[0], 0);
274 codegen_addxnullrefs(cd, mcodeptr);
275 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
276 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
277 M_ALD(REG_PV, REG_PV, disp);
278 M_JSR(REG_RA, REG_PV);
279 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
280 M_LDA(REG_PV, REG_RA, disp);
284 for (p = 0; p < INT_ARG_CNT; p++)
285 M_LLD(rd->argintregs[p], REG_SP, p * 8);
287 for (p = 0; p < FLT_ARG_CNT; p++)
288 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
290 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
295 /* call trace function */
298 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
299 M_AST(REG_RA, REG_SP, 1 * 8);
301 /* save integer argument registers */
303 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
304 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
306 /* save and copy float arguments into integer registers */
308 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
309 t = md->paramtypes[p].type;
311 if (IS_FLT_DBL_TYPE(t)) {
312 if (IS_2_WORD_TYPE(t)) {
313 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
316 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
319 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
322 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
326 disp = dseg_addaddress(cd, m);
327 M_ALD(REG_ITMP1, REG_PV, disp);
328 M_AST(REG_ITMP1, REG_SP, 0 * 8);
329 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
330 M_ALD(REG_PV, REG_PV, disp);
331 M_JSR(REG_RA, REG_PV);
332 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
333 M_LDA(REG_PV, REG_RA, disp);
334 M_ALD(REG_RA, REG_SP, 1 * 8);
336 /* restore integer argument registers */
338 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
339 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
341 /* restore float argument registers */
343 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
344 t = md->paramtypes[p].type;
346 if (IS_FLT_DBL_TYPE(t)) {
347 if (IS_2_WORD_TYPE(t)) {
348 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
351 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
355 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
359 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
364 /* end of header generation */
366 /* walk through all basic blocks */
368 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
370 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
372 if (bptr->flags >= BBREACHED) {
374 /* branch resolving */
378 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
379 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
380 brefs->branchpos, bptr->mpc);
384 /* copy interface registers to their destination */
391 while (src != NULL) {
393 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
394 /* d = reg_of_var(m, src, REG_ITMP1); */
395 if (!(src->flags & INMEMORY))
399 M_INTMOVE(REG_ITMP1, d);
400 store_reg_to_var_int(src, d);
406 while (src != NULL) {
408 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
409 d = reg_of_var(rd, src, REG_ITMP1);
410 M_INTMOVE(REG_ITMP1, d);
411 store_reg_to_var_int(src, d);
413 d = reg_of_var(rd, src, REG_IFTMP);
414 if ((src->varkind != STACKVAR)) {
416 if (IS_FLT_DBL_TYPE(s2)) {
417 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
418 s1 = rd->interfaces[len][s2].regoff;
421 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
423 store_reg_to_var_flt(src, d);
426 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
427 s1 = rd->interfaces[len][s2].regoff;
430 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
432 store_reg_to_var_int(src, d);
442 /* walk through all instructions */
447 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
448 if (iptr->line != currentline) {
449 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
450 currentline = iptr->line;
453 MCODECHECK(64); /* an instruction usually needs < 64 words */
456 case ICMD_INLINE_START:
457 case ICMD_INLINE_END:
460 case ICMD_NOP: /* ... ==> ... */
463 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
465 var_to_reg_int(s1, src, REG_ITMP1);
467 codegen_addxnullrefs(cd, mcodeptr);
470 /* constant operations ************************************************/
472 case ICMD_ICONST: /* ... ==> ..., constant */
473 /* op1 = 0, val.i = constant */
475 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
476 ICONST(d, iptr->val.i);
477 store_reg_to_var_int(iptr->dst, d);
480 case ICMD_LCONST: /* ... ==> ..., constant */
481 /* op1 = 0, val.l = constant */
483 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
484 LCONST(d, iptr->val.l);
485 store_reg_to_var_int(iptr->dst, d);
488 case ICMD_FCONST: /* ... ==> ..., constant */
489 /* op1 = 0, val.f = constant */
491 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
492 disp = dseg_addfloat(cd, iptr->val.f);
493 M_FLD(d, REG_PV, disp);
494 store_reg_to_var_flt(iptr->dst, d);
497 case ICMD_DCONST: /* ... ==> ..., constant */
498 /* op1 = 0, val.d = constant */
500 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
501 disp = dseg_adddouble(cd, iptr->val.d);
502 M_DLD(d, REG_PV, disp);
503 store_reg_to_var_flt(iptr->dst, d);
506 case ICMD_ACONST: /* ... ==> ..., constant */
507 /* op1 = 0, val.a = constant */
509 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
511 disp = dseg_addaddress(cd, iptr->val.a);
512 M_ALD(d, REG_PV, disp);
514 M_INTMOVE(REG_ZERO, d);
516 store_reg_to_var_int(iptr->dst, d);
520 /* load/store operations **********************************************/
522 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
523 case ICMD_LLOAD: /* op1 = local variable */
526 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
527 if ((iptr->dst->varkind == LOCALVAR) &&
528 (iptr->dst->varnum == iptr->op1))
530 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
531 if (var->flags & INMEMORY) {
532 M_LLD(d, REG_SP, var->regoff * 8);
534 M_INTMOVE(var->regoff, d);
536 store_reg_to_var_int(iptr->dst, d);
539 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
540 case ICMD_DLOAD: /* op1 = local variable */
542 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
543 if ((iptr->dst->varkind == LOCALVAR) &&
544 (iptr->dst->varnum == iptr->op1))
546 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
547 if (var->flags & INMEMORY) {
548 M_DLD(d, REG_SP, var->regoff * 8);
550 M_FLTMOVE(var->regoff, d);
552 store_reg_to_var_flt(iptr->dst, d);
556 case ICMD_ISTORE: /* ..., value ==> ... */
557 case ICMD_LSTORE: /* op1 = local variable */
560 if ((src->varkind == LOCALVAR) &&
561 (src->varnum == iptr->op1))
563 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
564 if (var->flags & INMEMORY) {
565 var_to_reg_int(s1, src, REG_ITMP1);
566 M_LST(s1, REG_SP, var->regoff * 8);
568 var_to_reg_int(s1, src, var->regoff);
569 M_INTMOVE(s1, var->regoff);
573 case ICMD_FSTORE: /* ..., value ==> ... */
574 case ICMD_DSTORE: /* op1 = local variable */
576 if ((src->varkind == LOCALVAR) &&
577 (src->varnum == iptr->op1))
579 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
580 if (var->flags & INMEMORY) {
581 var_to_reg_flt(s1, src, REG_FTMP1);
582 M_DST(s1, REG_SP, var->regoff * 8);
584 var_to_reg_flt(s1, src, var->regoff);
585 M_FLTMOVE(s1, var->regoff);
590 /* pop/dup/swap operations ********************************************/
592 /* attention: double and longs are only one entry in CACAO ICMDs */
594 case ICMD_POP: /* ..., value ==> ... */
595 case ICMD_POP2: /* ..., value, value ==> ... */
598 case ICMD_DUP: /* ..., a ==> ..., a, a */
599 M_COPY(src, iptr->dst);
602 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
604 M_COPY(src, iptr->dst);
605 M_COPY(src->prev, iptr->dst->prev);
606 M_COPY(iptr->dst, iptr->dst->prev->prev);
609 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
611 M_COPY(src, iptr->dst);
612 M_COPY(src->prev, iptr->dst->prev);
613 M_COPY(src->prev->prev, iptr->dst->prev->prev);
614 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
617 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
619 M_COPY(src, iptr->dst);
620 M_COPY(src->prev, iptr->dst->prev);
623 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, 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);
629 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
632 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
634 M_COPY(src, iptr->dst);
635 M_COPY(src->prev, iptr->dst->prev);
636 M_COPY(src->prev->prev, iptr->dst->prev->prev);
637 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
638 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
639 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
642 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
644 M_COPY(src, iptr->dst->prev);
645 M_COPY(src->prev, iptr->dst);
649 /* integer operations *************************************************/
651 case ICMD_INEG: /* ..., value ==> ..., - value */
653 var_to_reg_int(s1, src, REG_ITMP1);
654 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
655 M_ISUB(REG_ZERO, s1, d);
656 store_reg_to_var_int(iptr->dst, d);
659 case ICMD_LNEG: /* ..., value ==> ..., - value */
661 var_to_reg_int(s1, src, REG_ITMP1);
662 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
663 M_LSUB(REG_ZERO, s1, d);
664 store_reg_to_var_int(iptr->dst, d);
667 case ICMD_I2L: /* ..., value ==> ..., value */
669 var_to_reg_int(s1, src, REG_ITMP1);
670 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
672 store_reg_to_var_int(iptr->dst, d);
675 case ICMD_L2I: /* ..., value ==> ..., value */
677 var_to_reg_int(s1, src, REG_ITMP1);
678 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
679 M_IADD(s1, REG_ZERO, d);
680 store_reg_to_var_int(iptr->dst, d);
683 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
685 var_to_reg_int(s1, src, REG_ITMP1);
686 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
687 if (has_ext_instr_set) {
690 M_SLL_IMM(s1, 56, d);
691 M_SRA_IMM( d, 56, d);
693 store_reg_to_var_int(iptr->dst, d);
696 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
698 var_to_reg_int(s1, src, REG_ITMP1);
699 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
701 store_reg_to_var_int(iptr->dst, d);
704 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
706 var_to_reg_int(s1, src, REG_ITMP1);
707 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
708 if (has_ext_instr_set) {
711 M_SLL_IMM(s1, 48, d);
712 M_SRA_IMM( d, 48, d);
714 store_reg_to_var_int(iptr->dst, d);
718 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
720 var_to_reg_int(s1, src->prev, REG_ITMP1);
721 var_to_reg_int(s2, src, REG_ITMP2);
722 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
724 store_reg_to_var_int(iptr->dst, d);
727 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
728 /* val.i = constant */
730 var_to_reg_int(s1, src, REG_ITMP1);
731 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
732 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
733 M_IADD_IMM(s1, iptr->val.i, d);
735 ICONST(REG_ITMP2, iptr->val.i);
736 M_IADD(s1, REG_ITMP2, d);
738 store_reg_to_var_int(iptr->dst, d);
741 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
743 var_to_reg_int(s1, src->prev, REG_ITMP1);
744 var_to_reg_int(s2, src, REG_ITMP2);
745 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
747 store_reg_to_var_int(iptr->dst, d);
750 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
751 /* val.l = constant */
753 var_to_reg_int(s1, src, REG_ITMP1);
754 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
755 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
756 M_LADD_IMM(s1, iptr->val.l, d);
758 LCONST(REG_ITMP2, iptr->val.l);
759 M_LADD(s1, REG_ITMP2, d);
761 store_reg_to_var_int(iptr->dst, d);
764 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
766 var_to_reg_int(s1, src->prev, REG_ITMP1);
767 var_to_reg_int(s2, src, REG_ITMP2);
768 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
770 store_reg_to_var_int(iptr->dst, d);
773 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
774 /* val.i = constant */
776 var_to_reg_int(s1, src, REG_ITMP1);
777 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
778 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
779 M_ISUB_IMM(s1, iptr->val.i, d);
781 ICONST(REG_ITMP2, iptr->val.i);
782 M_ISUB(s1, REG_ITMP2, d);
784 store_reg_to_var_int(iptr->dst, d);
787 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
789 var_to_reg_int(s1, src->prev, REG_ITMP1);
790 var_to_reg_int(s2, src, REG_ITMP2);
791 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
793 store_reg_to_var_int(iptr->dst, d);
796 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
797 /* val.l = constant */
799 var_to_reg_int(s1, src, REG_ITMP1);
800 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
801 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
802 M_LSUB_IMM(s1, iptr->val.l, d);
804 LCONST(REG_ITMP2, iptr->val.l);
805 M_LSUB(s1, REG_ITMP2, d);
807 store_reg_to_var_int(iptr->dst, d);
810 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
812 var_to_reg_int(s1, src->prev, REG_ITMP1);
813 var_to_reg_int(s2, src, REG_ITMP2);
814 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
816 store_reg_to_var_int(iptr->dst, d);
819 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
820 /* val.i = constant */
822 var_to_reg_int(s1, src, REG_ITMP1);
823 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
824 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
825 M_IMUL_IMM(s1, iptr->val.i, d);
827 ICONST(REG_ITMP2, iptr->val.i);
828 M_IMUL(s1, REG_ITMP2, d);
830 store_reg_to_var_int(iptr->dst, d);
833 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
835 var_to_reg_int(s1, src->prev, REG_ITMP1);
836 var_to_reg_int(s2, src, REG_ITMP2);
837 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
839 store_reg_to_var_int(iptr->dst, d);
842 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
843 /* val.l = constant */
845 var_to_reg_int(s1, src, REG_ITMP1);
846 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
847 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
848 M_LMUL_IMM(s1, iptr->val.l, d);
850 LCONST(REG_ITMP2, iptr->val.l);
851 M_LMUL(s1, REG_ITMP2, d);
853 store_reg_to_var_int(iptr->dst, d);
856 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
857 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
859 var_to_reg_int(s1, src->prev, REG_ITMP1);
860 var_to_reg_int(s2, src, REG_ITMP2);
861 d = reg_of_var(rd, iptr->dst, REG_RESULT);
863 codegen_addxdivrefs(cd, mcodeptr);
865 M_MOV(s1, rd->argintregs[0]);
866 M_MOV(s2, rd->argintregs[1]);
868 disp = dseg_addaddress(cd, bte->fp);
869 M_ALD(REG_PV, REG_PV, disp);
870 M_JSR(REG_RA, REG_PV);
871 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
872 M_LDA(REG_PV, REG_RA, -disp);
874 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
875 store_reg_to_var_int(iptr->dst, d);
878 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
879 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
881 var_to_reg_int(s1, src->prev, REG_ITMP1);
882 var_to_reg_int(s2, src, REG_ITMP2);
883 d = reg_of_var(rd, iptr->dst, REG_RESULT);
885 codegen_addxdivrefs(cd, mcodeptr);
887 M_MOV(s1, rd->argintregs[0]);
888 M_MOV(s2, rd->argintregs[1]);
890 disp = dseg_addaddress(cd, bte->fp);
891 M_ALD(REG_PV, REG_PV, disp);
892 M_JSR(REG_RA, REG_PV);
893 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
894 M_LDA(REG_PV, REG_RA, -disp);
896 M_INTMOVE(REG_RESULT, d);
897 store_reg_to_var_int(iptr->dst, d);
900 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
901 case ICMD_LDIVPOW2: /* val.i = constant */
903 var_to_reg_int(s1, src, REG_ITMP1);
904 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
905 if (iptr->val.i <= 15) {
906 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
907 M_CMOVGE(s1, s1, REG_ITMP2);
909 M_SRA_IMM(s1, 63, REG_ITMP2);
910 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
911 M_LADD(s1, REG_ITMP2, REG_ITMP2);
913 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
914 store_reg_to_var_int(iptr->dst, d);
917 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
919 var_to_reg_int(s1, src->prev, REG_ITMP1);
920 var_to_reg_int(s2, src, REG_ITMP2);
921 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
922 M_AND_IMM(s2, 0x1f, REG_ITMP3);
923 M_SLL(s1, REG_ITMP3, d);
924 M_IADD(d, REG_ZERO, d);
925 store_reg_to_var_int(iptr->dst, d);
928 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
929 /* val.i = constant */
931 var_to_reg_int(s1, src, REG_ITMP1);
932 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
933 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
934 M_IADD(d, REG_ZERO, d);
935 store_reg_to_var_int(iptr->dst, d);
938 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
940 var_to_reg_int(s1, src->prev, REG_ITMP1);
941 var_to_reg_int(s2, src, REG_ITMP2);
942 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
943 M_AND_IMM(s2, 0x1f, REG_ITMP3);
944 M_SRA(s1, REG_ITMP3, d);
945 store_reg_to_var_int(iptr->dst, d);
948 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
949 /* val.i = constant */
951 var_to_reg_int(s1, src, REG_ITMP1);
952 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
953 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
954 store_reg_to_var_int(iptr->dst, d);
957 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
959 var_to_reg_int(s1, src->prev, REG_ITMP1);
960 var_to_reg_int(s2, src, REG_ITMP2);
961 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
962 M_AND_IMM(s2, 0x1f, REG_ITMP2);
964 M_SRL(d, REG_ITMP2, d);
965 M_IADD(d, REG_ZERO, d);
966 store_reg_to_var_int(iptr->dst, d);
969 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
970 /* val.i = constant */
972 var_to_reg_int(s1, src, REG_ITMP1);
973 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
975 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
976 M_IADD(d, REG_ZERO, d);
977 store_reg_to_var_int(iptr->dst, d);
980 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
982 var_to_reg_int(s1, src->prev, REG_ITMP1);
983 var_to_reg_int(s2, src, REG_ITMP2);
984 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
986 store_reg_to_var_int(iptr->dst, d);
989 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
990 /* val.i = constant */
992 var_to_reg_int(s1, src, REG_ITMP1);
993 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
994 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
995 store_reg_to_var_int(iptr->dst, d);
998 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1000 var_to_reg_int(s1, src->prev, REG_ITMP1);
1001 var_to_reg_int(s2, src, REG_ITMP2);
1002 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1004 store_reg_to_var_int(iptr->dst, d);
1007 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1008 /* val.i = constant */
1010 var_to_reg_int(s1, src, REG_ITMP1);
1011 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1012 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1013 store_reg_to_var_int(iptr->dst, d);
1016 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1018 var_to_reg_int(s1, src->prev, REG_ITMP1);
1019 var_to_reg_int(s2, src, REG_ITMP2);
1020 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1022 store_reg_to_var_int(iptr->dst, d);
1025 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1026 /* val.i = constant */
1028 var_to_reg_int(s1, src, REG_ITMP1);
1029 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1030 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1031 store_reg_to_var_int(iptr->dst, d);
1034 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1037 var_to_reg_int(s1, src->prev, REG_ITMP1);
1038 var_to_reg_int(s2, src, REG_ITMP2);
1039 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1041 store_reg_to_var_int(iptr->dst, d);
1044 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1045 /* val.i = constant */
1047 var_to_reg_int(s1, src, REG_ITMP1);
1048 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1049 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1050 M_AND_IMM(s1, iptr->val.i, d);
1051 } else if (iptr->val.i == 0xffff) {
1053 } else if (iptr->val.i == 0xffffff) {
1054 M_ZAPNOT_IMM(s1, 0x07, d);
1056 ICONST(REG_ITMP2, iptr->val.i);
1057 M_AND(s1, REG_ITMP2, d);
1059 store_reg_to_var_int(iptr->dst, d);
1062 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1063 /* val.i = constant */
1065 var_to_reg_int(s1, src, REG_ITMP1);
1066 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1068 M_MOV(s1, REG_ITMP1);
1071 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1072 M_AND_IMM(s1, iptr->val.i, d);
1074 M_ISUB(REG_ZERO, s1, d);
1075 M_AND_IMM(d, iptr->val.i, d);
1076 } else if (iptr->val.i == 0xffff) {
1079 M_ISUB(REG_ZERO, s1, d);
1081 } else if (iptr->val.i == 0xffffff) {
1082 M_ZAPNOT_IMM(s1, 0x07, d);
1084 M_ISUB(REG_ZERO, s1, d);
1085 M_ZAPNOT_IMM(d, 0x07, d);
1087 ICONST(REG_ITMP2, iptr->val.i);
1088 M_AND(s1, REG_ITMP2, d);
1090 M_ISUB(REG_ZERO, s1, d);
1091 M_AND(d, REG_ITMP2, d);
1093 M_ISUB(REG_ZERO, d, d);
1094 store_reg_to_var_int(iptr->dst, d);
1097 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1098 /* val.l = constant */
1100 var_to_reg_int(s1, src, REG_ITMP1);
1101 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1102 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1103 M_AND_IMM(s1, iptr->val.l, d);
1104 } else if (iptr->val.l == 0xffffL) {
1106 } else if (iptr->val.l == 0xffffffL) {
1107 M_ZAPNOT_IMM(s1, 0x07, d);
1108 } else if (iptr->val.l == 0xffffffffL) {
1110 } else if (iptr->val.l == 0xffffffffffL) {
1111 M_ZAPNOT_IMM(s1, 0x1f, d);
1112 } else if (iptr->val.l == 0xffffffffffffL) {
1113 M_ZAPNOT_IMM(s1, 0x3f, d);
1114 } else if (iptr->val.l == 0xffffffffffffffL) {
1115 M_ZAPNOT_IMM(s1, 0x7f, d);
1117 LCONST(REG_ITMP2, iptr->val.l);
1118 M_AND(s1, REG_ITMP2, d);
1120 store_reg_to_var_int(iptr->dst, d);
1123 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1124 /* val.l = constant */
1126 var_to_reg_int(s1, src, REG_ITMP1);
1127 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1129 M_MOV(s1, REG_ITMP1);
1132 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1133 M_AND_IMM(s1, iptr->val.l, d);
1135 M_LSUB(REG_ZERO, s1, d);
1136 M_AND_IMM(d, iptr->val.l, d);
1137 } else if (iptr->val.l == 0xffffL) {
1140 M_LSUB(REG_ZERO, s1, d);
1142 } else if (iptr->val.l == 0xffffffL) {
1143 M_ZAPNOT_IMM(s1, 0x07, d);
1145 M_LSUB(REG_ZERO, s1, d);
1146 M_ZAPNOT_IMM(d, 0x07, d);
1147 } else if (iptr->val.l == 0xffffffffL) {
1150 M_LSUB(REG_ZERO, s1, d);
1152 } else if (iptr->val.l == 0xffffffffffL) {
1153 M_ZAPNOT_IMM(s1, 0x1f, d);
1155 M_LSUB(REG_ZERO, s1, d);
1156 M_ZAPNOT_IMM(d, 0x1f, d);
1157 } else if (iptr->val.l == 0xffffffffffffL) {
1158 M_ZAPNOT_IMM(s1, 0x3f, d);
1160 M_LSUB(REG_ZERO, s1, d);
1161 M_ZAPNOT_IMM(d, 0x3f, d);
1162 } else if (iptr->val.l == 0xffffffffffffffL) {
1163 M_ZAPNOT_IMM(s1, 0x7f, d);
1165 M_LSUB(REG_ZERO, s1, d);
1166 M_ZAPNOT_IMM(d, 0x7f, d);
1168 LCONST(REG_ITMP2, iptr->val.l);
1169 M_AND(s1, REG_ITMP2, d);
1171 M_LSUB(REG_ZERO, s1, d);
1172 M_AND(d, REG_ITMP2, d);
1174 M_LSUB(REG_ZERO, d, d);
1175 store_reg_to_var_int(iptr->dst, d);
1178 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1181 var_to_reg_int(s1, src->prev, REG_ITMP1);
1182 var_to_reg_int(s2, src, REG_ITMP2);
1183 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1185 store_reg_to_var_int(iptr->dst, d);
1188 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1189 /* val.i = constant */
1191 var_to_reg_int(s1, src, REG_ITMP1);
1192 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1193 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1194 M_OR_IMM(s1, iptr->val.i, d);
1196 ICONST(REG_ITMP2, iptr->val.i);
1197 M_OR(s1, REG_ITMP2, d);
1199 store_reg_to_var_int(iptr->dst, d);
1202 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1203 /* val.l = constant */
1205 var_to_reg_int(s1, src, REG_ITMP1);
1206 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1207 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1208 M_OR_IMM(s1, iptr->val.l, d);
1210 LCONST(REG_ITMP2, iptr->val.l);
1211 M_OR(s1, REG_ITMP2, d);
1213 store_reg_to_var_int(iptr->dst, d);
1216 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1219 var_to_reg_int(s1, src->prev, REG_ITMP1);
1220 var_to_reg_int(s2, src, REG_ITMP2);
1221 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1223 store_reg_to_var_int(iptr->dst, d);
1226 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1227 /* val.i = constant */
1229 var_to_reg_int(s1, src, REG_ITMP1);
1230 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1231 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1232 M_XOR_IMM(s1, iptr->val.i, d);
1234 ICONST(REG_ITMP2, iptr->val.i);
1235 M_XOR(s1, REG_ITMP2, d);
1237 store_reg_to_var_int(iptr->dst, d);
1240 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1241 /* val.l = constant */
1243 var_to_reg_int(s1, src, REG_ITMP1);
1244 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1245 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1246 M_XOR_IMM(s1, iptr->val.l, d);
1248 LCONST(REG_ITMP2, iptr->val.l);
1249 M_XOR(s1, REG_ITMP2, d);
1251 store_reg_to_var_int(iptr->dst, d);
1255 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1257 var_to_reg_int(s1, src->prev, REG_ITMP1);
1258 var_to_reg_int(s2, src, REG_ITMP2);
1259 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1260 M_CMPLT(s1, s2, REG_ITMP3);
1261 M_CMPLT(s2, s1, REG_ITMP1);
1262 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1263 store_reg_to_var_int(iptr->dst, d);
1267 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1268 /* op1 = variable, val.i = constant */
1270 var = &(rd->locals[iptr->op1][TYPE_INT]);
1271 if (var->flags & INMEMORY) {
1273 M_LLD(s1, REG_SP, var->regoff * 8);
1276 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1277 M_IADD_IMM(s1, iptr->val.i, s1);
1278 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1279 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1281 M_LDA (s1, s1, iptr->val.i);
1282 M_IADD(s1, REG_ZERO, s1);
1284 if (var->flags & INMEMORY)
1285 M_LST(s1, REG_SP, var->regoff * 8);
1289 /* floating operations ************************************************/
1291 case ICMD_FNEG: /* ..., value ==> ..., - value */
1293 var_to_reg_flt(s1, src, REG_FTMP1);
1294 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1296 store_reg_to_var_flt(iptr->dst, d);
1299 case ICMD_DNEG: /* ..., value ==> ..., - value */
1301 var_to_reg_flt(s1, src, REG_FTMP1);
1302 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1304 store_reg_to_var_flt(iptr->dst, d);
1307 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1309 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1310 var_to_reg_flt(s2, src, REG_FTMP2);
1311 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1315 if (d == s1 || d == s2) {
1316 M_FADDS(s1, s2, REG_FTMP3);
1318 M_FMOV(REG_FTMP3, d);
1324 store_reg_to_var_flt(iptr->dst, d);
1327 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1329 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1330 var_to_reg_flt(s2, src, REG_FTMP2);
1331 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1335 if (d == s1 || d == s2) {
1336 M_DADDS(s1, s2, REG_FTMP3);
1338 M_FMOV(REG_FTMP3, d);
1344 store_reg_to_var_flt(iptr->dst, d);
1347 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1349 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1350 var_to_reg_flt(s2, src, REG_FTMP2);
1351 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1355 if (d == s1 || d == s2) {
1356 M_FSUBS(s1, s2, REG_FTMP3);
1358 M_FMOV(REG_FTMP3, d);
1364 store_reg_to_var_flt(iptr->dst, d);
1367 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1369 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1370 var_to_reg_flt(s2, src, REG_FTMP2);
1371 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1375 if (d == s1 || d == s2) {
1376 M_DSUBS(s1, s2, REG_FTMP3);
1378 M_FMOV(REG_FTMP3, d);
1384 store_reg_to_var_flt(iptr->dst, d);
1387 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1389 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1390 var_to_reg_flt(s2, src, REG_FTMP2);
1391 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1395 if (d == s1 || d == s2) {
1396 M_FMULS(s1, s2, REG_FTMP3);
1398 M_FMOV(REG_FTMP3, d);
1404 store_reg_to_var_flt(iptr->dst, d);
1407 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1409 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1410 var_to_reg_flt(s2, src, REG_FTMP2);
1411 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1415 if (d == s1 || d == s2) {
1416 M_DMULS(s1, s2, REG_FTMP3);
1418 M_FMOV(REG_FTMP3, d);
1424 store_reg_to_var_flt(iptr->dst, d);
1427 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1429 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1430 var_to_reg_flt(s2, src, REG_FTMP2);
1431 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1435 if (d == s1 || d == s2) {
1436 M_FDIVS(s1, s2, REG_FTMP3);
1438 M_FMOV(REG_FTMP3, d);
1444 store_reg_to_var_flt(iptr->dst, d);
1447 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1449 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1450 var_to_reg_flt(s2, src, REG_FTMP2);
1451 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1455 if (d == s1 || d == s2) {
1456 M_DDIVS(s1, s2, REG_FTMP3);
1458 M_FMOV(REG_FTMP3, d);
1464 store_reg_to_var_flt(iptr->dst, d);
1467 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1469 var_to_reg_int(s1, src, REG_ITMP1);
1470 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1471 disp = dseg_adddouble(cd, 0.0);
1472 M_LST(s1, REG_PV, disp);
1473 M_DLD(d, REG_PV, disp);
1475 store_reg_to_var_flt(iptr->dst, d);
1478 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1480 var_to_reg_int(s1, src, REG_ITMP1);
1481 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1482 disp = dseg_adddouble(cd, 0.0);
1483 M_LST(s1, REG_PV, disp);
1484 M_DLD(d, REG_PV, disp);
1486 store_reg_to_var_flt(iptr->dst, d);
1489 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1491 var_to_reg_flt(s1, src, REG_FTMP1);
1492 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1493 disp = dseg_adddouble(cd, 0.0);
1494 M_CVTDL_C(s1, REG_FTMP2);
1495 M_CVTLI(REG_FTMP2, REG_FTMP3);
1496 M_DST(REG_FTMP3, REG_PV, disp);
1497 M_ILD(d, REG_PV, disp);
1498 store_reg_to_var_int(iptr->dst, d);
1501 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1503 var_to_reg_flt(s1, src, REG_FTMP1);
1504 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1505 disp = dseg_adddouble(cd, 0.0);
1506 M_CVTDL_C(s1, REG_FTMP2);
1507 M_DST(REG_FTMP2, REG_PV, disp);
1508 M_LLD(d, REG_PV, disp);
1509 store_reg_to_var_int(iptr->dst, d);
1512 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1514 var_to_reg_flt(s1, src, REG_FTMP1);
1515 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1518 store_reg_to_var_flt(iptr->dst, d);
1521 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1523 var_to_reg_flt(s1, src, REG_FTMP1);
1524 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1531 store_reg_to_var_flt(iptr->dst, d);
1534 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1536 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1537 var_to_reg_flt(s2, src, REG_FTMP2);
1538 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1540 M_LSUB_IMM(REG_ZERO, 1, d);
1541 M_FCMPEQ(s1, s2, REG_FTMP3);
1542 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1544 M_FCMPLT(s2, s1, REG_FTMP3);
1545 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1546 M_LADD_IMM(REG_ZERO, 1, d);
1548 M_LSUB_IMM(REG_ZERO, 1, d);
1549 M_FCMPEQS(s1, s2, REG_FTMP3);
1551 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1553 M_FCMPLTS(s2, s1, REG_FTMP3);
1555 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1556 M_LADD_IMM(REG_ZERO, 1, d);
1558 store_reg_to_var_int(iptr->dst, d);
1561 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1563 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1564 var_to_reg_flt(s2, src, REG_FTMP2);
1565 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1567 M_LADD_IMM(REG_ZERO, 1, d);
1568 M_FCMPEQ(s1, s2, REG_FTMP3);
1569 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1571 M_FCMPLT(s1, s2, REG_FTMP3);
1572 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1573 M_LSUB_IMM(REG_ZERO, 1, d);
1575 M_LADD_IMM(REG_ZERO, 1, d);
1576 M_FCMPEQS(s1, s2, REG_FTMP3);
1578 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1580 M_FCMPLTS(s1, s2, REG_FTMP3);
1582 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1583 M_LSUB_IMM(REG_ZERO, 1, d);
1585 store_reg_to_var_int(iptr->dst, d);
1589 /* memory operations **************************************************/
1591 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1593 var_to_reg_int(s1, src, REG_ITMP1);
1594 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1595 gen_nullptr_check(s1);
1596 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1597 store_reg_to_var_int(iptr->dst, d);
1600 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1602 var_to_reg_int(s1, src->prev, REG_ITMP1);
1603 var_to_reg_int(s2, src, REG_ITMP2);
1604 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1605 if (iptr->op1 == 0) {
1606 gen_nullptr_check(s1);
1609 if (has_ext_instr_set) {
1610 M_LADD (s2, s1, REG_ITMP1);
1611 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1614 M_LADD(s2, s1, REG_ITMP1);
1615 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1616 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1617 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1618 M_SRA_IMM(d, 56, d);
1620 store_reg_to_var_int(iptr->dst, d);
1623 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1625 var_to_reg_int(s1, src->prev, REG_ITMP1);
1626 var_to_reg_int(s2, src, REG_ITMP2);
1627 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1628 if (iptr->op1 == 0) {
1629 gen_nullptr_check(s1);
1632 if (has_ext_instr_set) {
1633 M_LADD(s2, s1, REG_ITMP1);
1634 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1635 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1637 M_LADD (s2, s1, REG_ITMP1);
1638 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1639 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1640 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1641 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1643 store_reg_to_var_int(iptr->dst, d);
1646 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1648 var_to_reg_int(s1, src->prev, REG_ITMP1);
1649 var_to_reg_int(s2, src, REG_ITMP2);
1650 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1651 if (iptr->op1 == 0) {
1652 gen_nullptr_check(s1);
1655 if (has_ext_instr_set) {
1656 M_LADD(s2, s1, REG_ITMP1);
1657 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1658 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1661 M_LADD(s2, s1, REG_ITMP1);
1662 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1663 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1664 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1665 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1666 M_SRA_IMM(d, 48, d);
1668 store_reg_to_var_int(iptr->dst, d);
1671 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1673 var_to_reg_int(s1, src->prev, REG_ITMP1);
1674 var_to_reg_int(s2, src, REG_ITMP2);
1675 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1676 if (iptr->op1 == 0) {
1677 gen_nullptr_check(s1);
1680 M_S4ADDQ(s2, s1, REG_ITMP1);
1681 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1682 store_reg_to_var_int(iptr->dst, d);
1685 case ICMD_LALOAD: /* ..., 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_S8ADDQ(s2, s1, REG_ITMP1);
1695 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1696 store_reg_to_var_int(iptr->dst, d);
1699 case ICMD_FALOAD: /* ..., 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_FTMP2);
1704 if (iptr->op1 == 0) {
1705 gen_nullptr_check(s1);
1708 M_S4ADDQ(s2, s1, REG_ITMP1);
1709 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1710 store_reg_to_var_flt(iptr->dst, d);
1713 case ICMD_DALOAD: /* ..., 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_S8ADDQ(s2, s1, REG_ITMP1);
1723 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1724 store_reg_to_var_flt(iptr->dst, d);
1727 case ICMD_AALOAD: /* ..., 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_ITMP2);
1732 if (iptr->op1 == 0) {
1733 gen_nullptr_check(s1);
1736 M_SAADDQ(s2, s1, REG_ITMP1);
1737 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1738 store_reg_to_var_int(iptr->dst, d);
1742 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1744 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1745 var_to_reg_int(s2, src->prev, REG_ITMP2);
1746 if (iptr->op1 == 0) {
1747 gen_nullptr_check(s1);
1750 var_to_reg_int(s3, src, REG_ITMP3);
1751 if (has_ext_instr_set) {
1752 M_LADD(s2, s1, REG_ITMP1);
1753 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1755 M_LADD(s2, s1, REG_ITMP1);
1756 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1757 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1758 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1759 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1760 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1761 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1765 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1767 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1768 var_to_reg_int(s2, src->prev, REG_ITMP2);
1769 if (iptr->op1 == 0) {
1770 gen_nullptr_check(s1);
1773 var_to_reg_int(s3, src, REG_ITMP3);
1774 if (has_ext_instr_set) {
1775 M_LADD(s2, s1, REG_ITMP1);
1776 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1777 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1779 M_LADD(s2, s1, REG_ITMP1);
1780 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1781 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1782 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1783 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1784 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1785 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1786 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1790 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1792 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1793 var_to_reg_int(s2, src->prev, REG_ITMP2);
1794 if (iptr->op1 == 0) {
1795 gen_nullptr_check(s1);
1798 var_to_reg_int(s3, src, REG_ITMP3);
1799 if (has_ext_instr_set) {
1800 M_LADD(s2, s1, REG_ITMP1);
1801 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1802 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1804 M_LADD(s2, s1, REG_ITMP1);
1805 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1806 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1807 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1808 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1809 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1810 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1811 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1815 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1817 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1818 var_to_reg_int(s2, src->prev, REG_ITMP2);
1819 if (iptr->op1 == 0) {
1820 gen_nullptr_check(s1);
1823 var_to_reg_int(s3, src, REG_ITMP3);
1824 M_S4ADDQ(s2, s1, REG_ITMP1);
1825 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1828 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1830 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1831 var_to_reg_int(s2, src->prev, REG_ITMP2);
1832 if (iptr->op1 == 0) {
1833 gen_nullptr_check(s1);
1836 var_to_reg_int(s3, src, REG_ITMP3);
1837 M_S8ADDQ(s2, s1, REG_ITMP1);
1838 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1841 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1843 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1844 var_to_reg_int(s2, src->prev, REG_ITMP2);
1845 if (iptr->op1 == 0) {
1846 gen_nullptr_check(s1);
1849 var_to_reg_flt(s3, src, REG_FTMP3);
1850 M_S4ADDQ(s2, s1, REG_ITMP1);
1851 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1854 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1856 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1857 var_to_reg_int(s2, src->prev, REG_ITMP2);
1858 if (iptr->op1 == 0) {
1859 gen_nullptr_check(s1);
1862 var_to_reg_flt(s3, src, REG_FTMP3);
1863 M_S8ADDQ(s2, s1, REG_ITMP1);
1864 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1867 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1869 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1870 var_to_reg_int(s2, src->prev, REG_ITMP2);
1871 /* if (iptr->op1 == 0) { */
1872 gen_nullptr_check(s1);
1875 var_to_reg_int(s3, src, REG_ITMP3);
1877 M_MOV(s1, rd->argintregs[0]);
1878 M_MOV(s3, rd->argintregs[1]);
1880 disp = dseg_addaddress(cd, bte->fp);
1881 M_ALD(REG_PV, REG_PV, disp);
1882 M_JSR(REG_RA, REG_PV);
1883 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1884 M_LDA(REG_PV, REG_RA, -disp);
1886 M_BEQZ(REG_RESULT, 0);
1887 codegen_addxstorerefs(cd, mcodeptr);
1889 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1890 var_to_reg_int(s2, src->prev, REG_ITMP2);
1891 var_to_reg_int(s3, src, REG_ITMP3);
1892 M_SAADDQ(s2, s1, REG_ITMP1);
1893 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1897 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1899 var_to_reg_int(s1, src->prev, REG_ITMP1);
1900 var_to_reg_int(s2, src, REG_ITMP2);
1901 if (iptr->op1 == 0) {
1902 gen_nullptr_check(s1);
1905 M_S4ADDQ(s2, s1, REG_ITMP1);
1906 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1909 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1911 var_to_reg_int(s1, src->prev, REG_ITMP1);
1912 var_to_reg_int(s2, src, REG_ITMP2);
1913 if (iptr->op1 == 0) {
1914 gen_nullptr_check(s1);
1917 M_S8ADDQ(s2, s1, REG_ITMP1);
1918 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1921 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1923 var_to_reg_int(s1, src->prev, REG_ITMP1);
1924 var_to_reg_int(s2, src, REG_ITMP2);
1925 if (iptr->op1 == 0) {
1926 gen_nullptr_check(s1);
1929 M_SAADDQ(s2, s1, REG_ITMP1);
1930 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1933 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1935 var_to_reg_int(s1, src->prev, REG_ITMP1);
1936 var_to_reg_int(s2, src, REG_ITMP2);
1937 if (iptr->op1 == 0) {
1938 gen_nullptr_check(s1);
1941 if (has_ext_instr_set) {
1942 M_LADD(s2, s1, REG_ITMP1);
1943 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1946 M_LADD(s2, s1, REG_ITMP1);
1947 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1948 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1949 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1950 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1951 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1952 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1956 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1958 var_to_reg_int(s1, src->prev, REG_ITMP1);
1959 var_to_reg_int(s2, src, REG_ITMP2);
1960 if (iptr->op1 == 0) {
1961 gen_nullptr_check(s1);
1964 if (has_ext_instr_set) {
1965 M_LADD(s2, s1, REG_ITMP1);
1966 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1967 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1970 M_LADD(s2, s1, REG_ITMP1);
1971 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1972 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1973 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1974 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1975 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1976 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1977 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1981 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1983 var_to_reg_int(s1, src->prev, REG_ITMP1);
1984 var_to_reg_int(s2, src, REG_ITMP2);
1985 if (iptr->op1 == 0) {
1986 gen_nullptr_check(s1);
1989 if (has_ext_instr_set) {
1990 M_LADD(s2, s1, REG_ITMP1);
1991 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1992 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1995 M_LADD(s2, s1, REG_ITMP1);
1996 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1997 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1998 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1999 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2000 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2001 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2002 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2007 case ICMD_GETSTATIC: /* ... ==> ..., value */
2008 /* op1 = type, val.a = field address */
2011 disp = dseg_addaddress(cd, 0);
2013 codegen_addpatchref(cd, mcodeptr,
2014 PATCHER_get_putstatic,
2015 (unresolved_field *) iptr->target, disp);
2017 if (opt_showdisassemble)
2022 fieldinfo *fi = iptr->val.a;
2024 disp = dseg_addaddress(cd, &(fi->value));
2026 if (!fi->class->initialized) {
2027 codegen_addpatchref(cd, mcodeptr,
2028 PATCHER_clinit, fi->class, 0);
2030 if (opt_showdisassemble)
2035 M_ALD(REG_ITMP1, REG_PV, disp);
2036 switch (iptr->op1) {
2038 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2039 M_ILD(d, REG_ITMP1, 0);
2040 store_reg_to_var_int(iptr->dst, d);
2043 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2044 M_LLD(d, REG_ITMP1, 0);
2045 store_reg_to_var_int(iptr->dst, d);
2048 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2049 M_ALD(d, REG_ITMP1, 0);
2050 store_reg_to_var_int(iptr->dst, d);
2053 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2054 M_FLD(d, REG_ITMP1, 0);
2055 store_reg_to_var_flt(iptr->dst, d);
2058 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2059 M_DLD(d, REG_ITMP1, 0);
2060 store_reg_to_var_flt(iptr->dst, d);
2065 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2066 /* op1 = type, val.a = field address */
2069 disp = dseg_addaddress(cd, 0);
2071 codegen_addpatchref(cd, mcodeptr,
2072 PATCHER_get_putstatic,
2073 (unresolved_field *) iptr->target, disp);
2075 if (opt_showdisassemble)
2079 fieldinfo *fi = iptr->val.a;
2081 disp = dseg_addaddress(cd, &(fi->value));
2083 if (!fi->class->initialized) {
2084 codegen_addpatchref(cd, mcodeptr,
2085 PATCHER_clinit, fi->class, 0);
2087 if (opt_showdisassemble)
2092 M_ALD(REG_ITMP1, REG_PV, disp);
2093 switch (iptr->op1) {
2095 var_to_reg_int(s2, src, REG_ITMP2);
2096 M_IST(s2, REG_ITMP1, 0);
2099 var_to_reg_int(s2, src, REG_ITMP2);
2100 M_LST(s2, REG_ITMP1, 0);
2103 var_to_reg_int(s2, src, REG_ITMP2);
2104 M_AST(s2, REG_ITMP1, 0);
2107 var_to_reg_flt(s2, src, REG_FTMP2);
2108 M_FST(s2, REG_ITMP1, 0);
2111 var_to_reg_flt(s2, src, REG_FTMP2);
2112 M_DST(s2, REG_ITMP1, 0);
2117 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2118 /* val = value (in current instruction) */
2119 /* op1 = type, val.a = field address (in */
2120 /* following NOP) */
2122 if (!iptr[1].val.a) {
2123 disp = dseg_addaddress(cd, 0);
2125 codegen_addpatchref(cd, mcodeptr,
2126 PATCHER_get_putstatic,
2127 (unresolved_field *) iptr[1].target, disp);
2129 if (opt_showdisassemble)
2133 fieldinfo *fi = iptr[1].val.a;
2135 disp = dseg_addaddress(cd, &(fi->value));
2137 if (!fi->class->initialized) {
2138 codegen_addpatchref(cd, mcodeptr,
2139 PATCHER_clinit, fi->class, 0);
2141 if (opt_showdisassemble)
2146 M_ALD(REG_ITMP1, REG_PV, disp);
2147 switch (iptr->op1) {
2149 M_IST(REG_ZERO, REG_ITMP1, 0);
2152 M_LST(REG_ZERO, REG_ITMP1, 0);
2155 M_AST(REG_ZERO, REG_ITMP1, 0);
2158 M_FST(REG_ZERO, REG_ITMP1, 0);
2161 M_DST(REG_ZERO, REG_ITMP1, 0);
2167 case ICMD_GETFIELD: /* ... ==> ..., value */
2168 /* op1 = type, val.i = field offset */
2170 var_to_reg_int(s1, src, REG_ITMP1);
2171 gen_nullptr_check(s1);
2174 codegen_addpatchref(cd, mcodeptr,
2175 PATCHER_get_putfield,
2176 (unresolved_field *) iptr->target, 0);
2178 if (opt_showdisassemble)
2184 disp = ((fieldinfo *) (iptr->val.a))->offset;
2187 switch (iptr->op1) {
2189 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2191 store_reg_to_var_int(iptr->dst, d);
2194 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2196 store_reg_to_var_int(iptr->dst, d);
2199 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2201 store_reg_to_var_int(iptr->dst, d);
2204 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2206 store_reg_to_var_flt(iptr->dst, d);
2209 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2211 store_reg_to_var_flt(iptr->dst, d);
2216 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2217 /* op1 = type, val.a = field address */
2219 var_to_reg_int(s1, src->prev, REG_ITMP1);
2220 gen_nullptr_check(s1);
2222 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2223 var_to_reg_int(s2, src, REG_ITMP2);
2225 var_to_reg_flt(s2, src, REG_FTMP2);
2229 codegen_addpatchref(cd, mcodeptr,
2230 PATCHER_get_putfield,
2231 (unresolved_field *) iptr->target, 0);
2233 if (opt_showdisassemble)
2239 disp = ((fieldinfo *) (iptr->val.a))->offset;
2242 switch (iptr->op1) {
2244 M_IST(s2, s1, disp);
2247 M_LST(s2, s1, disp);
2250 M_AST(s2, s1, disp);
2253 M_FST(s2, s1, disp);
2256 M_DST(s2, s1, disp);
2261 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2262 /* val = value (in current instruction) */
2263 /* op1 = type, val.a = field address (in */
2264 /* following NOP) */
2266 var_to_reg_int(s1, src, REG_ITMP1);
2267 gen_nullptr_check(s1);
2269 if (!iptr[1].val.a) {
2270 codegen_addpatchref(cd, mcodeptr,
2271 PATCHER_get_putfield,
2272 (unresolved_field *) iptr[1].target, 0);
2274 if (opt_showdisassemble)
2280 disp = ((fieldinfo *) (iptr[1].val.a))->offset;
2283 switch (iptr[1].op1) {
2285 M_IST(REG_ZERO, s1, disp);
2288 M_LST(REG_ZERO, s1, disp);
2291 M_AST(REG_ZERO, s1, disp);
2294 M_FST(REG_ZERO, s1, disp);
2297 M_DST(REG_ZERO, s1, disp);
2303 /* branch operations **************************************************/
2305 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2307 var_to_reg_int(s1, src, REG_ITMP1);
2308 M_INTMOVE(s1, REG_ITMP1_XPTR);
2309 disp = dseg_addaddress(cd, asm_handle_exception);
2310 M_ALD(REG_ITMP2, REG_PV, disp);
2311 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2312 M_NOP; /* nop ensures that XPC is less than the end */
2313 /* of basic block */
2317 case ICMD_GOTO: /* ... ==> ... */
2318 /* op1 = target JavaVM pc */
2320 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2324 case ICMD_JSR: /* ... ==> ... */
2325 /* op1 = target JavaVM pc */
2327 M_BSR(REG_ITMP1, 0);
2328 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2331 case ICMD_RET: /* ... ==> ... */
2332 /* op1 = local variable */
2334 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2335 if (var->flags & INMEMORY) {
2336 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2337 M_RET(REG_ZERO, REG_ITMP1);
2340 M_RET(REG_ZERO, var->regoff);
2344 case ICMD_IFNULL: /* ..., value ==> ... */
2345 /* op1 = target JavaVM pc */
2347 var_to_reg_int(s1, src, REG_ITMP1);
2349 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2352 case ICMD_IFNONNULL: /* ..., value ==> ... */
2353 /* op1 = target JavaVM pc */
2355 var_to_reg_int(s1, src, REG_ITMP1);
2357 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2360 case ICMD_IFEQ: /* ..., value ==> ... */
2361 /* op1 = target JavaVM pc, val.i = constant */
2363 var_to_reg_int(s1, src, REG_ITMP1);
2364 if (iptr->val.i == 0) {
2368 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2369 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2372 ICONST(REG_ITMP2, iptr->val.i);
2373 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2375 M_BNEZ(REG_ITMP1, 0);
2377 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2380 case ICMD_IFLT: /* ..., value ==> ... */
2381 /* op1 = target JavaVM pc, val.i = constant */
2383 var_to_reg_int(s1, src, REG_ITMP1);
2384 if (iptr->val.i == 0) {
2388 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2389 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2392 ICONST(REG_ITMP2, iptr->val.i);
2393 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2395 M_BNEZ(REG_ITMP1, 0);
2397 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2400 case ICMD_IFLE: /* ..., value ==> ... */
2401 /* op1 = target JavaVM pc, val.i = constant */
2403 var_to_reg_int(s1, src, REG_ITMP1);
2404 if (iptr->val.i == 0) {
2408 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2409 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2412 ICONST(REG_ITMP2, iptr->val.i);
2413 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2415 M_BNEZ(REG_ITMP1, 0);
2417 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2420 case ICMD_IFNE: /* ..., value ==> ... */
2421 /* op1 = target JavaVM pc, val.i = constant */
2423 var_to_reg_int(s1, src, REG_ITMP1);
2424 if (iptr->val.i == 0) {
2428 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2429 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2432 ICONST(REG_ITMP2, iptr->val.i);
2433 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2435 M_BEQZ(REG_ITMP1, 0);
2437 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2440 case ICMD_IFGT: /* ..., value ==> ... */
2441 /* op1 = target JavaVM pc, val.i = constant */
2443 var_to_reg_int(s1, src, REG_ITMP1);
2444 if (iptr->val.i == 0) {
2448 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2449 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2452 ICONST(REG_ITMP2, iptr->val.i);
2453 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2455 M_BEQZ(REG_ITMP1, 0);
2457 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2460 case ICMD_IFGE: /* ..., value ==> ... */
2461 /* op1 = target JavaVM pc, val.i = constant */
2463 var_to_reg_int(s1, src, REG_ITMP1);
2464 if (iptr->val.i == 0) {
2468 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2469 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2472 ICONST(REG_ITMP2, iptr->val.i);
2473 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2475 M_BEQZ(REG_ITMP1, 0);
2477 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2480 case ICMD_IF_LEQ: /* ..., value ==> ... */
2481 /* op1 = target JavaVM pc, val.l = constant */
2483 var_to_reg_int(s1, src, REG_ITMP1);
2484 if (iptr->val.l == 0) {
2488 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2489 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2492 LCONST(REG_ITMP2, iptr->val.l);
2493 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2495 M_BNEZ(REG_ITMP1, 0);
2497 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2500 case ICMD_IF_LLT: /* ..., value ==> ... */
2501 /* op1 = target JavaVM pc, val.l = constant */
2503 var_to_reg_int(s1, src, REG_ITMP1);
2504 if (iptr->val.l == 0) {
2508 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2509 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2512 LCONST(REG_ITMP2, iptr->val.l);
2513 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2515 M_BNEZ(REG_ITMP1, 0);
2517 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2520 case ICMD_IF_LLE: /* ..., value ==> ... */
2521 /* op1 = target JavaVM pc, val.l = constant */
2523 var_to_reg_int(s1, src, REG_ITMP1);
2524 if (iptr->val.l == 0) {
2528 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2529 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2532 LCONST(REG_ITMP2, iptr->val.l);
2533 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2535 M_BNEZ(REG_ITMP1, 0);
2537 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2540 case ICMD_IF_LNE: /* ..., value ==> ... */
2541 /* op1 = target JavaVM pc, val.l = constant */
2543 var_to_reg_int(s1, src, REG_ITMP1);
2544 if (iptr->val.l == 0) {
2548 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2549 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2552 LCONST(REG_ITMP2, iptr->val.l);
2553 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2555 M_BEQZ(REG_ITMP1, 0);
2557 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2560 case ICMD_IF_LGT: /* ..., value ==> ... */
2561 /* op1 = target JavaVM pc, val.l = constant */
2563 var_to_reg_int(s1, src, REG_ITMP1);
2564 if (iptr->val.l == 0) {
2568 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2569 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2572 LCONST(REG_ITMP2, iptr->val.l);
2573 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2575 M_BEQZ(REG_ITMP1, 0);
2577 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2580 case ICMD_IF_LGE: /* ..., value ==> ... */
2581 /* op1 = target JavaVM pc, val.l = constant */
2583 var_to_reg_int(s1, src, REG_ITMP1);
2584 if (iptr->val.l == 0) {
2588 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2589 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2592 LCONST(REG_ITMP2, iptr->val.l);
2593 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2595 M_BEQZ(REG_ITMP1, 0);
2597 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2600 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2601 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2602 case ICMD_IF_ACMPEQ:
2604 var_to_reg_int(s1, src->prev, REG_ITMP1);
2605 var_to_reg_int(s2, src, REG_ITMP2);
2606 M_CMPEQ(s1, s2, REG_ITMP1);
2607 M_BNEZ(REG_ITMP1, 0);
2608 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2611 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2612 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2613 case ICMD_IF_ACMPNE:
2615 var_to_reg_int(s1, src->prev, REG_ITMP1);
2616 var_to_reg_int(s2, src, REG_ITMP2);
2617 M_CMPEQ(s1, s2, REG_ITMP1);
2618 M_BEQZ(REG_ITMP1, 0);
2619 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2622 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2623 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2625 var_to_reg_int(s1, src->prev, REG_ITMP1);
2626 var_to_reg_int(s2, src, REG_ITMP2);
2627 M_CMPLT(s1, s2, REG_ITMP1);
2628 M_BNEZ(REG_ITMP1, 0);
2629 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2632 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2633 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2635 var_to_reg_int(s1, src->prev, REG_ITMP1);
2636 var_to_reg_int(s2, src, REG_ITMP2);
2637 M_CMPLE(s1, s2, REG_ITMP1);
2638 M_BEQZ(REG_ITMP1, 0);
2639 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2642 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2643 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2645 var_to_reg_int(s1, src->prev, REG_ITMP1);
2646 var_to_reg_int(s2, src, REG_ITMP2);
2647 M_CMPLE(s1, s2, REG_ITMP1);
2648 M_BNEZ(REG_ITMP1, 0);
2649 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2652 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2653 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2655 var_to_reg_int(s1, src->prev, REG_ITMP1);
2656 var_to_reg_int(s2, src, REG_ITMP2);
2657 M_CMPLT(s1, s2, REG_ITMP1);
2658 M_BEQZ(REG_ITMP1, 0);
2659 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2662 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2664 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2667 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2668 /* val.i = constant */
2670 var_to_reg_int(s1, src, REG_ITMP1);
2671 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2673 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2674 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2675 M_CMPEQ(s1, REG_ZERO, d);
2676 store_reg_to_var_int(iptr->dst, d);
2679 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2680 M_CMPEQ(s1, REG_ZERO, d);
2682 store_reg_to_var_int(iptr->dst, d);
2686 M_MOV(s1, REG_ITMP1);
2689 ICONST(d, iptr[1].val.i);
2691 if ((s3 >= 0) && (s3 <= 255)) {
2692 M_CMOVEQ_IMM(s1, s3, d);
2694 ICONST(REG_ITMP2, s3);
2695 M_CMOVEQ(s1, REG_ITMP2, d);
2697 store_reg_to_var_int(iptr->dst, d);
2700 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2701 /* val.i = constant */
2703 var_to_reg_int(s1, src, REG_ITMP1);
2704 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2706 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2707 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2708 M_CMPEQ(s1, REG_ZERO, d);
2709 store_reg_to_var_int(iptr->dst, d);
2712 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2713 M_CMPEQ(s1, REG_ZERO, d);
2715 store_reg_to_var_int(iptr->dst, d);
2719 M_MOV(s1, REG_ITMP1);
2722 ICONST(d, iptr[1].val.i);
2724 if ((s3 >= 0) && (s3 <= 255)) {
2725 M_CMOVNE_IMM(s1, s3, d);
2727 ICONST(REG_ITMP2, s3);
2728 M_CMOVNE(s1, REG_ITMP2, d);
2730 store_reg_to_var_int(iptr->dst, d);
2733 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2734 /* val.i = constant */
2736 var_to_reg_int(s1, src, REG_ITMP1);
2737 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2739 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2740 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2741 M_CMPLT(s1, REG_ZERO, d);
2742 store_reg_to_var_int(iptr->dst, d);
2745 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2746 M_CMPLE(REG_ZERO, s1, d);
2747 store_reg_to_var_int(iptr->dst, d);
2751 M_MOV(s1, REG_ITMP1);
2754 ICONST(d, iptr[1].val.i);
2756 if ((s3 >= 0) && (s3 <= 255)) {
2757 M_CMOVLT_IMM(s1, s3, d);
2759 ICONST(REG_ITMP2, s3);
2760 M_CMOVLT(s1, REG_ITMP2, d);
2762 store_reg_to_var_int(iptr->dst, d);
2765 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2766 /* val.i = constant */
2768 var_to_reg_int(s1, src, REG_ITMP1);
2769 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2771 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2772 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2773 M_CMPLE(REG_ZERO, s1, d);
2774 store_reg_to_var_int(iptr->dst, d);
2777 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2778 M_CMPLT(s1, REG_ZERO, d);
2779 store_reg_to_var_int(iptr->dst, d);
2783 M_MOV(s1, REG_ITMP1);
2786 ICONST(d, iptr[1].val.i);
2788 if ((s3 >= 0) && (s3 <= 255)) {
2789 M_CMOVGE_IMM(s1, s3, d);
2791 ICONST(REG_ITMP2, s3);
2792 M_CMOVGE(s1, REG_ITMP2, d);
2794 store_reg_to_var_int(iptr->dst, d);
2797 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2798 /* val.i = constant */
2800 var_to_reg_int(s1, src, REG_ITMP1);
2801 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2803 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2804 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2805 M_CMPLT(REG_ZERO, s1, d);
2806 store_reg_to_var_int(iptr->dst, d);
2809 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2810 M_CMPLE(s1, REG_ZERO, d);
2811 store_reg_to_var_int(iptr->dst, d);
2815 M_MOV(s1, REG_ITMP1);
2818 ICONST(d, iptr[1].val.i);
2820 if ((s3 >= 0) && (s3 <= 255)) {
2821 M_CMOVGT_IMM(s1, s3, d);
2823 ICONST(REG_ITMP2, s3);
2824 M_CMOVGT(s1, REG_ITMP2, d);
2826 store_reg_to_var_int(iptr->dst, d);
2829 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2830 /* val.i = constant */
2832 var_to_reg_int(s1, src, REG_ITMP1);
2833 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2835 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2836 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2837 M_CMPLE(s1, REG_ZERO, d);
2838 store_reg_to_var_int(iptr->dst, d);
2841 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2842 M_CMPLT(REG_ZERO, s1, d);
2843 store_reg_to_var_int(iptr->dst, d);
2847 M_MOV(s1, REG_ITMP1);
2850 ICONST(d, iptr[1].val.i);
2852 if ((s3 >= 0) && (s3 <= 255)) {
2853 M_CMOVLE_IMM(s1, s3, d);
2855 ICONST(REG_ITMP2, s3);
2856 M_CMOVLE(s1, REG_ITMP2, d);
2858 store_reg_to_var_int(iptr->dst, d);
2862 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2866 var_to_reg_int(s1, src, REG_RESULT);
2867 M_INTMOVE(s1, REG_RESULT);
2869 goto nowperformreturn;
2871 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2874 var_to_reg_flt(s1, src, REG_FRESULT);
2875 M_FLTMOVE(s1, REG_FRESULT);
2877 goto nowperformreturn;
2879 case ICMD_RETURN: /* ... ==> ... */
2885 p = parentargs_base;
2887 /* call trace function */
2890 M_LDA(REG_SP, REG_SP, -3 * 8);
2891 M_AST(REG_RA, REG_SP, 0 * 8);
2892 M_LST(REG_RESULT, REG_SP, 1 * 8);
2893 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2895 disp = dseg_addaddress(cd, m);
2896 M_ALD(rd->argintregs[0], REG_PV, disp);
2897 M_MOV(REG_RESULT, rd->argintregs[1]);
2898 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2899 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2901 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2902 M_ALD(REG_PV, REG_PV, disp);
2903 M_JSR(REG_RA, REG_PV);
2904 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2905 M_LDA(REG_PV, REG_RA, -disp);
2907 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2908 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2909 M_ALD(REG_RA, REG_SP, 0 * 8);
2910 M_LDA(REG_SP, REG_SP, 3 * 8);
2913 #if defined(USE_THREADS)
2914 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2917 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2919 switch (iptr->opc) {
2923 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2927 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2931 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2932 M_ALD(REG_PV, REG_PV, disp);
2933 M_JSR(REG_RA, REG_PV);
2934 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2935 M_LDA(REG_PV, REG_RA, disp);
2937 switch (iptr->opc) {
2941 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2945 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2951 /* restore return address */
2953 if (!m->isleafmethod) {
2954 p--; M_LLD(REG_RA, REG_SP, p * 8);
2957 /* restore saved registers */
2959 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2960 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2962 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2963 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2966 /* deallocate stack */
2968 if (parentargs_base) {
2969 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2972 M_RET(REG_ZERO, REG_RA);
2978 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2983 tptr = (void **) iptr->target;
2985 s4ptr = iptr->val.a;
2986 l = s4ptr[1]; /* low */
2987 i = s4ptr[2]; /* high */
2989 var_to_reg_int(s1, src, REG_ITMP1);
2991 M_INTMOVE(s1, REG_ITMP1);
2992 } else if (l <= 32768) {
2993 M_LDA(REG_ITMP1, s1, -l);
2995 ICONST(REG_ITMP2, l);
2996 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3003 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3005 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3006 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3008 M_BEQZ(REG_ITMP2, 0);
3009 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3011 /* build jump table top down and use address of lowest entry */
3013 /* s4ptr += 3 + i; */
3017 dseg_addtarget(cd, (basicblock *) tptr[0]);
3022 /* length of dataseg after last dseg_addtarget is used by load */
3024 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3025 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3026 M_JMP(REG_ZERO, REG_ITMP2);
3031 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3033 s4 i, l, val, *s4ptr;
3036 tptr = (void **) iptr->target;
3038 s4ptr = iptr->val.a;
3039 l = s4ptr[0]; /* default */
3040 i = s4ptr[1]; /* count */
3042 MCODECHECK((i<<2)+8);
3043 var_to_reg_int(s1, src, REG_ITMP1);
3049 if ((val >= 0) && (val <= 255)) {
3050 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3052 if ((val >= -32768) && (val <= 32767)) {
3053 M_LDA(REG_ITMP2, REG_ZERO, val);
3055 disp = dseg_adds4(cd, val);
3056 M_ILD(REG_ITMP2, REG_PV, disp);
3058 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3060 M_BNEZ(REG_ITMP2, 0);
3061 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3066 tptr = (void **) iptr->target;
3067 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3074 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3075 /* op1 = arg count val.a = builtintable entry */
3081 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3082 /* op1 = arg count, val.a = method pointer */
3084 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3085 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3086 case ICMD_INVOKEINTERFACE:
3091 md = lm->parseddesc;
3093 unresolved_method *um = iptr->target;
3094 md = um->methodref->parseddesc.md;
3098 s3 = md->paramcount;
3100 MCODECHECK((s3 << 1) + 64);
3102 /* copy arguments to registers or stack location */
3104 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3105 if (src->varkind == ARGVAR)
3107 if (IS_INT_LNG_TYPE(src->type)) {
3108 if (!md->params[s3].inmemory) {
3109 s1 = rd->argintregs[md->params[s3].regoff];
3110 var_to_reg_int(d, src, s1);
3113 var_to_reg_int(d, src, REG_ITMP1);
3114 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3118 if (!md->params[s3].inmemory) {
3119 s1 = rd->argfltregs[md->params[s3].regoff];
3120 var_to_reg_flt(d, src, s1);
3123 var_to_reg_flt(d, src, REG_FTMP1);
3124 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3129 switch (iptr->opc) {
3132 disp = dseg_addaddress(cd, NULL);
3134 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target,
3137 if (opt_showdisassemble)
3141 disp = dseg_addaddress(cd, bte->fp);
3144 d = md->returntype.type;
3146 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3147 M_JSR(REG_RA, REG_PV);
3148 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3149 M_LDA(REG_PV, REG_RA, -disp);
3151 /* if op1 == true, we need to check for an exception */
3153 if (iptr->op1 == true) {
3154 M_BEQZ(REG_RESULT, 0);
3155 codegen_addxexceptionrefs(cd, mcodeptr);
3159 case ICMD_INVOKESPECIAL:
3160 M_BEQZ(rd->argintregs[0], 0);
3161 codegen_addxnullrefs(cd, mcodeptr);
3164 case ICMD_INVOKESTATIC:
3166 unresolved_method *um = iptr->target;
3168 disp = dseg_addaddress(cd, NULL);
3170 codegen_addpatchref(cd, mcodeptr,
3171 PATCHER_invokestatic_special, um, disp);
3173 if (opt_showdisassemble)
3176 d = um->methodref->parseddesc.md->returntype.type;
3179 disp = dseg_addaddress(cd, lm->stubroutine);
3180 d = lm->parseddesc->returntype.type;
3183 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3184 M_JSR(REG_RA, REG_PV);
3185 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3186 M_LDA(REG_PV, REG_RA, -disp);
3189 case ICMD_INVOKEVIRTUAL:
3190 gen_nullptr_check(rd->argintregs[0]);
3193 unresolved_method *um = iptr->target;
3195 codegen_addpatchref(cd, mcodeptr,
3196 PATCHER_invokevirtual, um, 0);
3198 if (opt_showdisassemble)
3202 d = um->methodref->parseddesc.md->returntype.type;
3205 s1 = OFFSET(vftbl_t, table[0]) +
3206 sizeof(methodptr) * lm->vftblindex;
3207 d = lm->parseddesc->returntype.type;
3210 M_ALD(REG_METHODPTR, rd->argintregs[0],
3211 OFFSET(java_objectheader, vftbl));
3212 M_ALD(REG_PV, REG_METHODPTR, s1);
3213 M_JSR(REG_RA, REG_PV);
3214 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3215 M_LDA(REG_PV, REG_RA, -disp);
3218 case ICMD_INVOKEINTERFACE:
3219 gen_nullptr_check(rd->argintregs[0]);
3222 unresolved_method *um = iptr->target;
3224 codegen_addpatchref(cd, mcodeptr,
3225 PATCHER_invokeinterface, um, 0);
3227 if (opt_showdisassemble)
3232 d = um->methodref->parseddesc.md->returntype.type;
3235 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3236 sizeof(methodptr*) * lm->class->index;
3238 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3240 d = lm->parseddesc->returntype.type;
3243 M_ALD(REG_METHODPTR, rd->argintregs[0],
3244 OFFSET(java_objectheader, vftbl));
3245 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3246 M_ALD(REG_PV, REG_METHODPTR, s2);
3247 M_JSR(REG_RA, REG_PV);
3248 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3249 M_LDA(REG_PV, REG_RA, -disp);
3253 /* d contains return type */
3255 if (d != TYPE_VOID) {
3256 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3257 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3258 M_INTMOVE(REG_RESULT, s1);
3259 store_reg_to_var_int(iptr->dst, s1);
3261 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3262 M_FLTMOVE(REG_FRESULT, s1);
3263 store_reg_to_var_flt(iptr->dst, s1);
3269 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3271 /* op1: 0 == array, 1 == class */
3272 /* val.a: (classinfo*) superclass */
3274 /* superclass is an interface:
3276 * OK if ((sub == NULL) ||
3277 * (sub->vftbl->interfacetablelength > super->index) &&
3278 * (sub->vftbl->interfacetable[-super->index] != NULL));
3280 * superclass is a class:
3282 * OK if ((sub == NULL) || (0
3283 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3284 * super->vftbl->diffval));
3289 vftbl_t *supervftbl;
3292 super = (classinfo *) iptr->val.a;
3299 superindex = super->index;
3300 supervftbl = super->vftbl;
3303 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3304 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3306 var_to_reg_int(s1, src, REG_ITMP1);
3308 /* calculate interface checkcast code size */
3312 s2 += opt_showdisassemble ? 1 : 0;
3314 /* calculate class checkcast code size */
3316 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3318 s3 += opt_showdisassemble ? 1 : 0;
3320 /* if class is not resolved, check which code to call */
3323 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3325 disp = dseg_adds4(cd, 0); /* super->flags */
3327 codegen_addpatchref(cd, mcodeptr,
3328 PATCHER_checkcast_instanceof_flags,
3329 (constant_classref *) iptr->target, disp);
3331 if (opt_showdisassemble)
3334 M_ILD(REG_ITMP2, REG_PV, disp);
3335 disp = dseg_adds4(cd, ACC_INTERFACE);
3336 M_ILD(REG_ITMP3, REG_PV, disp);
3337 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3338 M_BEQZ(REG_ITMP2, s2 + 1);
3341 /* interface checkcast code */
3343 if (!super || (super->flags & ACC_INTERFACE)) {
3348 codegen_addpatchref(cd, mcodeptr,
3349 PATCHER_checkcast_instanceof_interface,
3350 (constant_classref *) iptr->target, 0);
3352 if (opt_showdisassemble)
3356 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3357 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3358 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3359 M_BLEZ(REG_ITMP3, 0);
3360 codegen_addxcastrefs(cd, mcodeptr);
3361 M_ALD(REG_ITMP3, REG_ITMP2,
3362 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3363 superindex * sizeof(methodptr*)));
3364 M_BEQZ(REG_ITMP3, 0);
3365 codegen_addxcastrefs(cd, mcodeptr);
3371 /* class checkcast code */
3373 if (!super || !(super->flags & ACC_INTERFACE)) {
3374 disp = dseg_addaddress(cd, supervftbl);
3380 codegen_addpatchref(cd, mcodeptr,
3381 PATCHER_checkcast_instanceof_class,
3382 (constant_classref *) iptr->target,
3385 if (opt_showdisassemble)
3389 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3390 M_ALD(REG_ITMP3, REG_PV, disp);
3391 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3392 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3394 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3395 /* if (s1 != REG_ITMP1) { */
3396 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3397 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3398 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3399 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3401 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3404 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3405 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3406 M_ALD(REG_ITMP3, REG_PV, disp);
3407 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3408 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3409 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3412 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3413 M_BEQZ(REG_ITMP3, 0);
3414 codegen_addxcastrefs(cd, mcodeptr);
3416 d = reg_of_var(rd, iptr->dst, s1);
3418 store_reg_to_var_int(iptr->dst, d);
3422 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
3423 /* op1: 1... resolved, 0... not resolved */
3425 var_to_reg_int(s1, src, rd->argintregs[0]);
3426 M_INTMOVE(s1, rd->argintregs[0]);
3430 disp = dseg_addaddress(cd, iptr->target);
3433 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target, disp);
3435 if (opt_showdisassemble)
3441 a = (ptrint) bte->fp;
3444 M_ALD(rd->argintregs[1], REG_PV, disp);
3446 disp = dseg_addaddress(cd, a);
3447 M_ALD(REG_PV, REG_PV, disp);
3448 M_JSR(REG_RA, REG_PV);
3449 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3450 M_LDA(REG_PV, REG_RA, -disp);
3452 M_BEQZ(REG_RESULT, 0);
3453 codegen_addxcastrefs(cd, mcodeptr);
3455 var_to_reg_int(s1, src, REG_ITMP1);
3456 d = reg_of_var(rd, iptr->dst, s1);
3458 store_reg_to_var_int(iptr->dst, d);
3461 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3463 /* op1: 0 == array, 1 == class */
3464 /* val.a: (classinfo*) superclass */
3466 /* superclass is an interface:
3468 * return (sub != NULL) &&
3469 * (sub->vftbl->interfacetablelength > super->index) &&
3470 * (sub->vftbl->interfacetable[-super->index] != NULL);
3472 * superclass is a class:
3474 * return ((sub != NULL) && (0
3475 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3476 * super->vftbl->diffvall));
3481 vftbl_t *supervftbl;
3484 super = (classinfo *) iptr->val.a;
3491 superindex = super->index;
3492 supervftbl = super->vftbl;
3495 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3496 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3498 var_to_reg_int(s1, src, REG_ITMP1);
3499 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3501 M_MOV(s1, REG_ITMP1);
3505 /* calculate interface instanceof code size */
3509 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3511 /* calculate class instanceof code size */
3515 s3 += (opt_showdisassemble ? 1 : 0);
3517 /* if class is not resolved, check which code to call */
3521 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3523 disp = dseg_adds4(cd, 0); /* super->flags */
3525 codegen_addpatchref(cd, mcodeptr,
3526 PATCHER_checkcast_instanceof_flags,
3527 (constant_classref *) iptr->target, disp);
3529 if (opt_showdisassemble)
3532 M_ILD(REG_ITMP3, REG_PV, disp);
3534 disp = dseg_adds4(cd, ACC_INTERFACE);
3535 M_ILD(REG_ITMP2, REG_PV, disp);
3536 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3537 M_BEQZ(REG_ITMP3, s2 + 1);
3540 /* interface instanceof code */
3542 if (!super || (super->flags & ACC_INTERFACE)) {
3548 /* If d == REG_ITMP2, then it's destroyed in check code */
3553 codegen_addpatchref(cd, mcodeptr,
3554 PATCHER_checkcast_instanceof_interface,
3555 (constant_classref *) iptr->target, 0);
3557 if (opt_showdisassemble)
3561 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3562 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3563 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3564 M_BLEZ(REG_ITMP3, 2);
3565 M_ALD(REG_ITMP1, REG_ITMP1,
3566 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3567 superindex * sizeof(methodptr*)));
3568 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3574 /* class instanceof code */
3576 if (!super || !(super->flags & ACC_INTERFACE)) {
3577 disp = dseg_addaddress(cd, supervftbl);
3584 codegen_addpatchref(cd, mcodeptr,
3585 PATCHER_checkcast_instanceof_class,
3586 (constant_classref *) iptr->target,
3589 if (opt_showdisassemble)
3593 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3594 M_ALD(REG_ITMP2, REG_PV, disp);
3595 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3596 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3598 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3599 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3600 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3601 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3602 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3604 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3605 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3607 store_reg_to_var_int(iptr->dst, d);
3611 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3612 /* op1 = dimension, val.a = array descriptor */
3614 /* check for negative sizes and copy sizes to stack if necessary */
3616 MCODECHECK((iptr->op1 << 1) + 64);
3618 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3619 /* copy SAVEDVAR sizes to stack */
3621 if (src->varkind != ARGVAR) {
3622 var_to_reg_int(s2, src, REG_ITMP1);
3623 M_LST(s2, REG_SP, s1 * 8);
3627 /* a0 = dimension count */
3629 ICONST(rd->argintregs[0], iptr->op1);
3631 /* is patcher function set? */
3634 disp = dseg_addaddress(cd, 0);
3636 codegen_addpatchref(cd, mcodeptr,
3637 (functionptr) iptr->target, iptr->val.a,
3640 if (opt_showdisassemble)
3644 disp = dseg_addaddress(cd, iptr->val.a);
3647 /* a1 = arraydescriptor */
3649 M_ALD(rd->argintregs[1], REG_PV, disp);
3651 /* a2 = pointer to dimensions = stack pointer */
3653 M_INTMOVE(REG_SP, rd->argintregs[2]);
3655 disp = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3656 M_ALD(REG_PV, REG_PV, disp);
3657 M_JSR(REG_RA, REG_PV);
3658 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3659 M_LDA(REG_PV, REG_RA, -disp);
3661 /* check for exception before result assignment */
3663 M_BEQZ(REG_RESULT, 0);
3664 codegen_addxexceptionrefs(cd, mcodeptr);
3666 d = reg_of_var(rd, iptr->dst, REG_RESULT);
3667 M_INTMOVE(REG_RESULT, d);
3668 store_reg_to_var_int(iptr->dst, d);
3672 throw_cacao_exception_exit(string_java_lang_InternalError,
3673 "Unknown ICMD %d", iptr->opc);
3676 } /* for instruction */
3678 /* copy values to interface registers */
3680 src = bptr->outstack;
3681 len = bptr->outdepth;
3688 if ((src->varkind != STACKVAR)) {
3690 if (IS_FLT_DBL_TYPE(s2)) {
3691 var_to_reg_flt(s1, src, REG_FTMP1);
3692 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3693 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3696 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3700 var_to_reg_int(s1, src, REG_ITMP1);
3701 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3702 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3705 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3711 } /* if (bptr -> flags >= BBREACHED) */
3712 } /* for basic block */
3714 codegen_createlinenumbertable(cd);
3718 s4 *xcodeptr = NULL;
3721 /* generate ArithmeticException stubs */
3723 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3724 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3725 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3727 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3731 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3733 (u1 *) mcodeptr - cd->mcodebase);
3737 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3739 if (xcodeptr != NULL) {
3740 disp = xcodeptr - mcodeptr - 1;
3744 xcodeptr = mcodeptr;
3746 M_MOV(REG_PV, rd->argintregs[0]);
3747 M_MOV(REG_SP, rd->argintregs[1]);
3748 M_ALD(rd->argintregs[2],
3749 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3750 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3752 M_LDA(REG_SP, REG_SP, -1 * 8);
3753 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3755 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3756 M_ALD(REG_PV, REG_PV, disp);
3757 M_JSR(REG_RA, REG_PV);
3758 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3759 M_LDA(REG_PV, REG_RA, -disp);
3761 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3763 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3764 M_LDA(REG_SP, REG_SP, 1 * 8);
3766 disp = dseg_addaddress(cd, asm_handle_exception);
3767 M_ALD(REG_ITMP3, REG_PV, disp);
3768 M_JMP(REG_ZERO, REG_ITMP3);
3772 /* generate ArrayIndexOutOfBoundsException stubs */
3776 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3777 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3779 (u1*) mcodeptr - cd->mcodebase);
3783 /* move index register into REG_ITMP1 */
3785 M_MOV(bref->reg, REG_ITMP1);
3786 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3788 if (xcodeptr != NULL) {
3789 disp = xcodeptr - mcodeptr - 1;
3793 xcodeptr = mcodeptr;
3795 M_MOV(REG_PV, rd->argintregs[0]);
3796 M_MOV(REG_SP, rd->argintregs[1]);
3798 if (m->isleafmethod)
3799 M_MOV(REG_RA, rd->argintregs[2]);
3801 M_ALD(rd->argintregs[2],
3802 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3804 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3805 M_MOV(REG_ITMP1, rd->argintregs[4]);
3807 M_LDA(REG_SP, REG_SP, -2 * 8);
3808 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3810 if (m->isleafmethod)
3811 M_AST(REG_RA, REG_SP, 1 * 8);
3813 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3814 M_ALD(REG_PV, REG_PV, disp);
3815 M_JSR(REG_RA, REG_PV);
3816 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3817 M_LDA(REG_PV, REG_RA, -disp);
3819 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3821 if (m->isleafmethod)
3822 M_ALD(REG_RA, REG_SP, 1 * 8);
3824 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3825 M_LDA(REG_SP, REG_SP, 2 * 8);
3827 disp = dseg_addaddress(cd, asm_handle_exception);
3828 M_ALD(REG_ITMP3, REG_PV, disp);
3829 M_JMP(REG_ZERO, REG_ITMP3);
3833 /* generate ArrayStoreException stubs */
3837 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3838 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3839 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3841 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3845 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3847 (u1 *) mcodeptr - cd->mcodebase);
3851 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3853 if (xcodeptr != NULL) {
3854 disp = xcodeptr - mcodeptr - 1;
3858 xcodeptr = mcodeptr;
3860 M_MOV(REG_PV, rd->argintregs[0]);
3861 M_MOV(REG_SP, rd->argintregs[1]);
3862 M_ALD(rd->argintregs[2],
3863 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3864 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3866 M_LDA(REG_SP, REG_SP, -1 * 8);
3867 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3869 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3870 M_ALD(REG_PV, REG_PV, disp);
3871 M_JSR(REG_RA, REG_PV);
3872 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3873 M_LDA(REG_PV, REG_RA, -disp);
3875 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3877 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3878 M_LDA(REG_SP, REG_SP, 1 * 8);
3880 disp = dseg_addaddress(cd, asm_handle_exception);
3881 M_ALD(REG_ITMP3, REG_PV, disp);
3882 M_JMP(REG_ZERO, REG_ITMP3);
3886 /* generate ClassCastException stubs */
3890 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3891 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3892 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3894 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3898 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3900 (u1 *) mcodeptr - cd->mcodebase);
3904 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3906 if (xcodeptr != NULL) {
3907 disp = xcodeptr - mcodeptr - 1;
3911 xcodeptr = mcodeptr;
3913 M_MOV(REG_PV, rd->argintregs[0]);
3914 M_MOV(REG_SP, rd->argintregs[1]);
3916 if (m->isleafmethod)
3917 M_MOV(REG_RA, rd->argintregs[2]);
3919 M_ALD(rd->argintregs[2],
3920 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3922 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3924 M_LDA(REG_SP, REG_SP, -2 * 8);
3925 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3927 if (m->isleafmethod)
3928 M_AST(REG_RA, REG_SP, 1 * 8);
3930 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3931 M_ALD(REG_PV, REG_PV, disp);
3932 M_JSR(REG_RA, REG_PV);
3933 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3934 M_LDA(REG_PV, REG_RA, -disp);
3936 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3938 if (m->isleafmethod)
3939 M_ALD(REG_RA, REG_SP, 1 * 8);
3941 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3942 M_LDA(REG_SP, REG_SP, 2 * 8);
3944 disp = dseg_addaddress(cd, asm_handle_exception);
3945 M_ALD(REG_ITMP3, REG_PV, disp);
3946 M_JMP(REG_ZERO, REG_ITMP3);
3950 /* generate NullPointerException stubs */
3954 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3955 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3956 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3958 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3962 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3964 (u1 *) mcodeptr - cd->mcodebase);
3968 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3970 if (xcodeptr != NULL) {
3971 disp = xcodeptr - mcodeptr - 1;
3975 xcodeptr = mcodeptr;
3977 M_MOV(REG_PV, rd->argintregs[0]);
3978 M_MOV(REG_SP, rd->argintregs[1]);
3980 if (m->isleafmethod)
3981 M_MOV(REG_RA, rd->argintregs[2]);
3983 M_ALD(rd->argintregs[2],
3984 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3986 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3988 M_LDA(REG_SP, REG_SP, -2 * 8);
3989 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3991 if (m->isleafmethod)
3992 M_AST(REG_RA, REG_SP, 1 * 8);
3994 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
3995 M_ALD(REG_PV, REG_PV, disp);
3996 M_JSR(REG_RA, REG_PV);
3997 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3998 M_LDA(REG_PV, REG_RA, -disp);
4000 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4002 if (m->isleafmethod)
4003 M_ALD(REG_RA, REG_SP, 1 * 8);
4005 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4006 M_LDA(REG_SP, REG_SP, 2 * 8);
4008 disp = dseg_addaddress(cd, asm_handle_exception);
4009 M_ALD(REG_ITMP3, REG_PV, disp);
4010 M_JMP(REG_ZERO, REG_ITMP3);
4014 /* generate exception check stubs */
4018 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4019 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4020 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4022 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4026 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4028 (u1 *) mcodeptr - cd->mcodebase);
4032 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4034 if (xcodeptr != NULL) {
4035 disp = xcodeptr - mcodeptr - 1;
4039 xcodeptr = mcodeptr;
4041 M_MOV(REG_PV, rd->argintregs[0]);
4042 M_MOV(REG_SP, rd->argintregs[1]);
4043 M_ALD(rd->argintregs[2],
4044 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4045 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4047 M_LDA(REG_SP, REG_SP, -1 * 8);
4048 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4050 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4051 M_ALD(REG_PV, REG_PV, disp);
4052 M_JSR(REG_RA, REG_PV);
4053 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4054 M_LDA(REG_PV, REG_RA, -disp);
4056 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4058 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4059 M_LDA(REG_SP, REG_SP, 1 * 8);
4061 disp = dseg_addaddress(cd, asm_handle_exception);
4062 M_ALD(REG_ITMP3, REG_PV, disp);
4063 M_JMP(REG_ZERO, REG_ITMP3);
4067 /* generate patcher stub call code */
4074 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4075 /* check code segment size */
4079 /* Get machine code which is patched back in later. The call is */
4080 /* 1 instruction word long. */
4082 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4085 /* patch in the call to call the following code (done at compile */
4088 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4089 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4091 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4093 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4095 /* create stack frame */
4097 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4099 /* move return address onto stack */
4101 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4103 /* move pointer to java_objectheader onto stack */
4105 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4106 /* create a virtual java_objectheader */
4108 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4109 disp = dseg_addaddress(cd, NULL); /* vftbl */
4111 M_LDA(REG_ITMP3, REG_PV, disp);
4112 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4114 M_AST(REG_ZERO, REG_SP, 4 * 8);
4117 /* move machine code onto stack */
4119 disp = dseg_adds4(cd, mcode);
4120 M_ILD(REG_ITMP3, REG_PV, disp);
4121 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4123 /* move class/method/field reference onto stack */
4125 disp = dseg_addaddress(cd, pref->ref);
4126 M_ALD(REG_ITMP3, REG_PV, disp);
4127 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4129 /* move data segment displacement onto stack */
4131 disp = dseg_adds4(cd, pref->disp);
4132 M_ILD(REG_ITMP3, REG_PV, disp);
4133 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4135 /* move patcher function pointer onto stack */
4137 disp = dseg_addaddress(cd, pref->patcher);
4138 M_ALD(REG_ITMP3, REG_PV, disp);
4139 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4141 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4142 M_ALD(REG_ITMP3, REG_PV, disp);
4143 M_JMP(REG_ZERO, REG_ITMP3);
4148 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4152 /* createcompilerstub **********************************************************
4154 Creates a stub routine which calls the compiler.
4156 *******************************************************************************/
4158 #define COMPSTUBSIZE 3
4160 functionptr createcompilerstub(methodinfo *m)
4162 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4163 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4165 /* code for the stub */
4166 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4167 M_JMP(0, REG_PV); /* jump to the compiler, return address
4168 in reg 0 is used as method pointer */
4169 s[1] = (ptrint) m; /* literals to be adressed */
4170 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4172 #if defined(STATISTICS)
4174 count_cstub_len += COMPSTUBSIZE * 8;
4177 return (functionptr) s;
4181 /* createnativestub ************************************************************
4183 Creates a stub routine which calls a native method.
4185 *******************************************************************************/
4187 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4188 registerdata *rd, methoddesc *nmd)
4190 s4 *mcodeptr; /* code generation pointer */
4191 s4 stackframesize; /* size of stackframe if needed */
4194 s4 i, j; /* count variables */
4197 s4 funcdisp; /* displacement of the function */
4199 /* initialize variables */
4202 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4205 /* calculate stack frame size */
4208 1 + /* return address */
4209 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4210 sizeof(localref_table) / SIZEOF_VOID_P +
4211 1 + /* methodinfo for call trace */
4212 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4216 /* create method header */
4218 (void) dseg_addaddress(cd, m); /* MethodPointer */
4219 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4220 (void) dseg_adds4(cd, 0); /* IsSync */
4221 (void) dseg_adds4(cd, 0); /* IsLeaf */
4222 (void) dseg_adds4(cd, 0); /* IntSave */
4223 (void) dseg_adds4(cd, 0); /* FltSave */
4224 (void) dseg_addlinenumbertablesize(cd);
4225 (void) dseg_adds4(cd, 0); /* ExTableSize */
4228 /* initialize mcode variables */
4230 mcodeptr = (s4 *) cd->mcodebase;
4231 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4234 /* generate stub code */
4236 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4237 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4240 /* call trace function */
4243 /* save integer argument registers */
4245 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4246 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4247 M_LST(rd->argintregs[i], REG_SP, j * 8);
4252 /* save and copy float arguments into integer registers */
4254 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4255 t = md->paramtypes[i].type;
4257 if (IS_FLT_DBL_TYPE(t)) {
4258 if (IS_2_WORD_TYPE(t)) {
4259 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4260 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4262 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4263 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4269 disp = dseg_addaddress(cd, m);
4270 M_ALD(REG_ITMP1, REG_PV, disp);
4271 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4272 disp = dseg_addaddress(cd, builtin_trace_args);
4273 M_ALD(REG_PV, REG_PV, disp);
4274 M_JSR(REG_RA, REG_PV);
4275 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4276 M_LDA(REG_PV, REG_RA, -disp);
4278 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4279 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4280 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4285 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4286 t = md->paramtypes[i].type;
4288 if (IS_FLT_DBL_TYPE(t)) {
4289 if (IS_2_WORD_TYPE(t)) {
4290 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4292 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4299 /* get function address (this must happen before the stackframeinfo) */
4301 funcdisp = dseg_addaddress(cd, f);
4303 #if !defined(ENABLE_STATICVM)
4305 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4307 if (opt_showdisassemble)
4312 /* save integer and float argument registers */
4314 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4315 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4316 M_LST(rd->argintregs[i], REG_SP, j * 8);
4321 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4322 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4323 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4328 /* prepare data structures for native function call */
4330 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4331 M_MOV(REG_PV, rd->argintregs[1]);
4332 M_LDA(rd->argintregs[2], REG_SP, stackframesize * 8);
4333 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4334 disp = dseg_addaddress(cd, codegen_start_native_call);
4335 M_ALD(REG_PV, REG_PV, disp);
4336 M_JSR(REG_RA, REG_PV);
4337 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4338 M_LDA(REG_PV, REG_RA, -disp);
4340 /* restore integer and float argument registers */
4342 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4343 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4344 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4349 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4350 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4351 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4356 /* copy or spill arguments to new locations */
4358 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4359 t = md->paramtypes[i].type;
4361 if (IS_INT_LNG_TYPE(t)) {
4362 if (!md->params[i].inmemory) {
4363 s1 = rd->argintregs[md->params[i].regoff];
4365 if (!nmd->params[j].inmemory) {
4366 s2 = rd->argintregs[nmd->params[j].regoff];
4370 s2 = nmd->params[j].regoff;
4371 M_LST(s1, REG_SP, s2 * 8);
4375 s1 = md->params[i].regoff + stackframesize;
4376 s2 = nmd->params[j].regoff;
4377 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4378 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4382 if (!md->params[i].inmemory) {
4383 s1 = rd->argfltregs[md->params[i].regoff];
4385 if (!nmd->params[j].inmemory) {
4386 s2 = rd->argfltregs[nmd->params[j].regoff];
4390 s2 = nmd->params[j].regoff;
4391 if (IS_2_WORD_TYPE(t))
4392 M_DST(s1, REG_SP, s2 * 8);
4394 M_FST(s1, REG_SP, s2 * 8);
4398 s1 = md->params[i].regoff + stackframesize;
4399 s2 = nmd->params[j].regoff;
4400 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4401 if (IS_2_WORD_TYPE(t))
4402 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4404 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4409 /* put class into second argument register */
4411 if (m->flags & ACC_STATIC) {
4412 disp = dseg_addaddress(cd, m->class);
4413 M_ALD(rd->argintregs[1], REG_PV, disp);
4416 /* put env into first argument register */
4418 disp = dseg_addaddress(cd, &env);
4419 M_ALD(rd->argintregs[0], REG_PV, disp);
4421 /* do the native function call */
4423 M_ALD(REG_PV, REG_PV, funcdisp);
4424 M_JSR(REG_RA, REG_PV); /* call native method */
4425 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4426 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4428 /* save return value */
4430 if (IS_INT_LNG_TYPE(md->returntype.type))
4431 M_LST(REG_RESULT, REG_SP, 0 * 8);
4433 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4435 /* remove native stackframe info */
4437 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4438 disp = dseg_addaddress(cd, codegen_finish_native_call);
4439 M_ALD(REG_PV, REG_PV, disp);
4440 M_JSR(REG_RA, REG_PV);
4441 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4442 M_LDA(REG_PV, REG_RA, -disp);
4444 /* call finished trace */
4447 /* just restore the value we need, don't care about the other */
4449 if (IS_INT_LNG_TYPE(md->returntype.type))
4450 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4452 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4454 disp = dseg_addaddress(cd, m);
4455 M_ALD(rd->argintregs[0], REG_PV, disp);
4457 M_MOV(REG_RESULT, rd->argintregs[1]);
4458 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4459 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4461 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4462 M_ALD(REG_PV, REG_PV, disp);
4463 M_JSR(REG_RA, REG_PV);
4464 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4465 M_LDA(REG_PV, REG_RA, -disp);
4468 /* check for exception */
4470 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4471 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4472 M_ALD(REG_PV, REG_PV, disp);
4473 M_JSR(REG_RA, REG_PV);
4474 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4475 M_LDA(REG_PV, REG_RA, -disp);
4476 M_MOV(REG_RESULT, REG_ITMP3);
4478 disp = dseg_addaddress(cd, &_exceptionptr);
4479 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4481 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4483 /* restore return value */
4485 if (IS_INT_LNG_TYPE(md->returntype.type))
4486 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4488 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4490 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4492 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4493 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4494 M_RET(REG_ZERO, REG_RA); /* return to caller */
4496 /* handle exception */
4498 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4500 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4501 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4503 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4505 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4506 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4507 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4510 /* process patcher calls **************************************************/
4518 /* there can only be one <clinit> ref entry */
4519 pref = cd->patchrefs;
4521 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4522 /* Get machine code which is patched back in later. The call is */
4523 /* 1 instruction word long. */
4525 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4526 mcode = (u4) *xcodeptr;
4528 /* patch in the call to call the following code (done at compile */
4531 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4532 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4534 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4536 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4538 /* create stack frame */
4540 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4542 /* move return address onto stack */
4544 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4546 /* move pointer to java_objectheader onto stack */
4548 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4549 /* create a virtual java_objectheader */
4551 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4552 disp = dseg_addaddress(cd, NULL); /* vftbl */
4554 M_LDA(REG_ITMP3, REG_PV, disp);
4555 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4557 M_AST(REG_ZERO, REG_SP, 4 * 8);
4560 /* move machine code onto stack */
4562 disp = dseg_adds4(cd, mcode);
4563 M_ILD(REG_ITMP3, REG_PV, disp);
4564 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4566 /* move class/method/field reference onto stack */
4568 disp = dseg_addaddress(cd, pref->ref);
4569 M_ALD(REG_ITMP3, REG_PV, disp);
4570 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4572 /* move data segment displacement onto stack */
4574 disp = dseg_adds4(cd, pref->disp);
4575 M_ILD(REG_ITMP3, REG_PV, disp);
4576 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4578 /* move patcher function pointer onto stack */
4580 disp = dseg_addaddress(cd, pref->patcher);
4581 M_ALD(REG_ITMP3, REG_PV, disp);
4582 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4584 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4585 M_ALD(REG_ITMP3, REG_PV, disp);
4586 M_JMP(REG_ZERO, REG_ITMP3);
4590 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4592 return m->entrypoint;
4597 * These are local overrides for various environment variables in Emacs.
4598 * Please do not remove this and leave it at the end of the file, where
4599 * Emacs will automagically detect them.
4600 * ---------------------------------------------------------------------
4603 * indent-tabs-mode: t