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 3345 2005-10-04 22:14:53Z twisti $
48 #include "vm/jit/alpha/arch.h"
49 #include "vm/jit/alpha/codegen.h"
51 #include "cacao/cacao.h"
52 #include "native/native.h"
53 #include "vm/builtin.h"
54 #include "vm/global.h"
55 #include "vm/loader.h"
56 #include "vm/stringlocal.h"
57 #include "vm/tables.h"
58 #include "vm/jit/asmpart.h"
59 #include "vm/jit/codegen.inc"
60 #include "vm/jit/jit.h"
63 # include "vm/jit/lsra.h"
64 # include "vm/jit/lsra.inc"
67 #include "vm/jit/parse.h"
68 #include "vm/jit/patcher.h"
69 #include "vm/jit/reg.h"
70 #include "vm/jit/reg.inc"
73 /* codegen *********************************************************************
75 Generates machine code.
77 *******************************************************************************/
79 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
81 s4 len, s1, s2, s3, d, disp;
91 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
92 builtintable_entry *bte;
95 /* prevent compiler warnings */
106 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
108 /* space to save used callee saved registers */
110 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
111 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
113 parentargs_base = rd->memuse + savedregs_num;
115 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
117 if (checksync && (m->flags & ACC_SYNCHRONIZED))
122 /* create method header */
124 (void) dseg_addaddress(cd, m); /* MethodPointer */
125 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
127 #if defined(USE_THREADS)
129 /* IsSync contains the offset relative to the stack pointer for the
130 argument of monitor_exit used in the exception handler. Since the
131 offset could be zero and give a wrong meaning of the flag it is
135 if (checksync && (m->flags & ACC_SYNCHRONIZED))
136 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
141 (void) dseg_adds4(cd, 0); /* IsSync */
143 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
144 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */
145 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */
147 dseg_addlinenumbertablesize(cd);
149 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
151 /* create exception table */
153 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
154 dseg_addtarget(cd, ex->start);
155 dseg_addtarget(cd, ex->end);
156 dseg_addtarget(cd, ex->handler);
157 (void) dseg_addaddress(cd, ex->catchtype.cls);
160 /* initialize mcode variables */
162 mcodeptr = (s4 *) cd->mcodebase;
163 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
164 MCODECHECK(128 + m->paramcount);
166 /* create stack frame (if necessary) */
168 if (parentargs_base) {
169 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
172 /* save return address and used callee saved registers */
175 if (!m->isleafmethod) {
176 p--; M_AST(REG_RA, REG_SP, p * 8);
178 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
179 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
181 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
182 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
185 /* take arguments out of register or stack frame */
189 for (p = 0, l = 0; p < md->paramcount; p++) {
190 t = md->paramtypes[p].type;
191 var = &(rd->locals[l][t]);
193 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
197 s1 = md->params[p].regoff;
198 if (IS_INT_LNG_TYPE(t)) { /* integer args */
199 if (!md->params[p].inmemory) { /* register arguments */
200 s2 = rd->argintregs[s1];
201 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
202 M_INTMOVE(s2, var->regoff);
204 } else { /* reg arg -> spilled */
205 M_LST(s2, REG_SP, var->regoff * 8);
208 } else { /* stack arguments */
209 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
210 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
212 } else { /* stack arg -> spilled */
213 var->regoff = parentargs_base + s1;
217 } else { /* floating args */
218 if (!md->params[p].inmemory) { /* register arguments */
219 s2 = rd->argfltregs[s1];
220 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
221 M_FLTMOVE(s2, var->regoff);
223 } else { /* reg arg -> spilled */
224 M_DST(s2, REG_SP, var->regoff * 8);
227 } else { /* stack arguments */
228 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
229 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
231 } else { /* stack-arg -> spilled */
232 var->regoff = parentargs_base + s1;
238 /* call monitorenter function */
240 #if defined(USE_THREADS)
241 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
242 /* stack offset for monitor argument */
247 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
249 for (p = 0; p < INT_ARG_CNT; p++)
250 M_LST(rd->argintregs[p], REG_SP, p * 8);
252 for (p = 0; p < FLT_ARG_CNT; p++)
253 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
255 s1 += INT_ARG_CNT + FLT_ARG_CNT;
258 /* decide which monitor enter function to call */
260 if (m->flags & ACC_STATIC) {
261 disp = dseg_addaddress(cd, m->class);
262 M_ALD(REG_ITMP1, REG_PV, disp);
263 M_AST(REG_ITMP1, REG_SP, s1 * 8);
264 M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
265 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
266 M_ALD(REG_PV, REG_PV, disp);
267 M_JSR(REG_RA, REG_PV);
268 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
269 M_LDA(REG_PV, REG_RA, disp);
272 M_BEQZ(rd->argintregs[0], 0);
273 codegen_addxnullrefs(cd, mcodeptr);
274 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
275 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
276 M_ALD(REG_PV, REG_PV, disp);
277 M_JSR(REG_RA, REG_PV);
278 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
279 M_LDA(REG_PV, REG_RA, disp);
283 for (p = 0; p < INT_ARG_CNT; p++)
284 M_LLD(rd->argintregs[p], REG_SP, p * 8);
286 for (p = 0; p < FLT_ARG_CNT; p++)
287 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
289 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
294 /* call trace function */
297 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
298 M_AST(REG_RA, REG_SP, 1 * 8);
300 /* save integer argument registers */
302 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
303 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
305 /* save and copy float arguments into integer registers */
307 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
308 t = md->paramtypes[p].type;
310 if (IS_FLT_DBL_TYPE(t)) {
311 if (IS_2_WORD_TYPE(t)) {
312 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
315 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
318 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
321 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
325 disp = dseg_addaddress(cd, m);
326 M_ALD(REG_ITMP1, REG_PV, disp);
327 M_AST(REG_ITMP1, REG_SP, 0 * 8);
328 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
329 M_ALD(REG_PV, REG_PV, disp);
330 M_JSR(REG_RA, REG_PV);
331 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
332 M_LDA(REG_PV, REG_RA, disp);
333 M_ALD(REG_RA, REG_SP, 1 * 8);
335 /* restore integer argument registers */
337 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
338 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
340 /* restore float argument registers */
342 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
343 t = md->paramtypes[p].type;
345 if (IS_FLT_DBL_TYPE(t)) {
346 if (IS_2_WORD_TYPE(t)) {
347 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
350 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
354 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
358 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
363 /* end of header generation */
365 /* walk through all basic blocks */
367 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
369 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
371 if (bptr->flags >= BBREACHED) {
373 /* branch resolving */
377 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
378 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
379 brefs->branchpos, bptr->mpc);
383 /* copy interface registers to their destination */
390 while (src != NULL) {
392 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
393 /* d = reg_of_var(m, src, REG_ITMP1); */
394 if (!(src->flags & INMEMORY))
398 M_INTMOVE(REG_ITMP1, d);
399 store_reg_to_var_int(src, d);
405 while (src != NULL) {
407 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
408 d = reg_of_var(rd, src, REG_ITMP1);
409 M_INTMOVE(REG_ITMP1, d);
410 store_reg_to_var_int(src, d);
412 d = reg_of_var(rd, src, REG_IFTMP);
413 if ((src->varkind != STACKVAR)) {
415 if (IS_FLT_DBL_TYPE(s2)) {
416 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
417 s1 = rd->interfaces[len][s2].regoff;
420 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
422 store_reg_to_var_flt(src, d);
425 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
426 s1 = rd->interfaces[len][s2].regoff;
429 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
431 store_reg_to_var_int(src, d);
441 /* walk through all instructions */
446 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
447 if (iptr->line != currentline) {
448 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
449 currentline = iptr->line;
452 MCODECHECK(64); /* an instruction usually needs < 64 words */
455 case ICMD_INLINE_START:
456 case ICMD_INLINE_END:
459 case ICMD_NOP: /* ... ==> ... */
462 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
464 var_to_reg_int(s1, src, REG_ITMP1);
466 codegen_addxnullrefs(cd, mcodeptr);
469 /* constant operations ************************************************/
471 case ICMD_ICONST: /* ... ==> ..., constant */
472 /* op1 = 0, val.i = constant */
474 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
475 ICONST(d, iptr->val.i);
476 store_reg_to_var_int(iptr->dst, d);
479 case ICMD_LCONST: /* ... ==> ..., constant */
480 /* op1 = 0, val.l = constant */
482 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
483 LCONST(d, iptr->val.l);
484 store_reg_to_var_int(iptr->dst, d);
487 case ICMD_FCONST: /* ... ==> ..., constant */
488 /* op1 = 0, val.f = constant */
490 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
491 disp = dseg_addfloat(cd, iptr->val.f);
492 M_FLD(d, REG_PV, disp);
493 store_reg_to_var_flt(iptr->dst, d);
496 case ICMD_DCONST: /* ... ==> ..., constant */
497 /* op1 = 0, val.d = constant */
499 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
500 disp = dseg_adddouble(cd, iptr->val.d);
501 M_DLD(d, REG_PV, disp);
502 store_reg_to_var_flt(iptr->dst, d);
505 case ICMD_ACONST: /* ... ==> ..., constant */
506 /* op1 = 0, val.a = constant */
508 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
510 disp = dseg_addaddress(cd, iptr->val.a);
511 M_ALD(d, REG_PV, disp);
513 M_INTMOVE(REG_ZERO, d);
515 store_reg_to_var_int(iptr->dst, d);
519 /* load/store operations **********************************************/
521 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
522 case ICMD_LLOAD: /* op1 = local variable */
525 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
526 if ((iptr->dst->varkind == LOCALVAR) &&
527 (iptr->dst->varnum == iptr->op1))
529 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
530 if (var->flags & INMEMORY) {
531 M_LLD(d, REG_SP, var->regoff * 8);
533 M_INTMOVE(var->regoff, d);
535 store_reg_to_var_int(iptr->dst, d);
538 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
539 case ICMD_DLOAD: /* op1 = local variable */
541 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
542 if ((iptr->dst->varkind == LOCALVAR) &&
543 (iptr->dst->varnum == iptr->op1))
545 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
546 if (var->flags & INMEMORY) {
547 M_DLD(d, REG_SP, var->regoff * 8);
549 M_FLTMOVE(var->regoff, d);
551 store_reg_to_var_flt(iptr->dst, d);
555 case ICMD_ISTORE: /* ..., value ==> ... */
556 case ICMD_LSTORE: /* op1 = local variable */
559 if ((src->varkind == LOCALVAR) &&
560 (src->varnum == iptr->op1))
562 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
563 if (var->flags & INMEMORY) {
564 var_to_reg_int(s1, src, REG_ITMP1);
565 M_LST(s1, REG_SP, var->regoff * 8);
567 var_to_reg_int(s1, src, var->regoff);
568 M_INTMOVE(s1, var->regoff);
572 case ICMD_FSTORE: /* ..., value ==> ... */
573 case ICMD_DSTORE: /* op1 = local variable */
575 if ((src->varkind == LOCALVAR) &&
576 (src->varnum == iptr->op1))
578 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
579 if (var->flags & INMEMORY) {
580 var_to_reg_flt(s1, src, REG_FTMP1);
581 M_DST(s1, REG_SP, var->regoff * 8);
583 var_to_reg_flt(s1, src, var->regoff);
584 M_FLTMOVE(s1, var->regoff);
589 /* pop/dup/swap operations ********************************************/
591 /* attention: double and longs are only one entry in CACAO ICMDs */
593 case ICMD_POP: /* ..., value ==> ... */
594 case ICMD_POP2: /* ..., value, value ==> ... */
597 case ICMD_DUP: /* ..., a ==> ..., a, a */
598 M_COPY(src, iptr->dst);
601 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
603 M_COPY(src, iptr->dst);
604 M_COPY(src->prev, iptr->dst->prev);
605 M_COPY(iptr->dst, iptr->dst->prev->prev);
608 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
610 M_COPY(src, iptr->dst);
611 M_COPY(src->prev, iptr->dst->prev);
612 M_COPY(src->prev->prev, iptr->dst->prev->prev);
613 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
616 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
618 M_COPY(src, iptr->dst);
619 M_COPY(src->prev, iptr->dst->prev);
622 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
624 M_COPY(src, iptr->dst);
625 M_COPY(src->prev, iptr->dst->prev);
626 M_COPY(src->prev->prev, iptr->dst->prev->prev);
627 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
628 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
631 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
633 M_COPY(src, iptr->dst);
634 M_COPY(src->prev, iptr->dst->prev);
635 M_COPY(src->prev->prev, iptr->dst->prev->prev);
636 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
637 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
638 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
641 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
643 M_COPY(src, iptr->dst->prev);
644 M_COPY(src->prev, iptr->dst);
648 /* integer operations *************************************************/
650 case ICMD_INEG: /* ..., value ==> ..., - value */
652 var_to_reg_int(s1, src, REG_ITMP1);
653 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
654 M_ISUB(REG_ZERO, s1, d);
655 store_reg_to_var_int(iptr->dst, d);
658 case ICMD_LNEG: /* ..., value ==> ..., - value */
660 var_to_reg_int(s1, src, REG_ITMP1);
661 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
662 M_LSUB(REG_ZERO, s1, d);
663 store_reg_to_var_int(iptr->dst, d);
666 case ICMD_I2L: /* ..., value ==> ..., value */
668 var_to_reg_int(s1, src, REG_ITMP1);
669 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
671 store_reg_to_var_int(iptr->dst, d);
674 case ICMD_L2I: /* ..., value ==> ..., value */
676 var_to_reg_int(s1, src, REG_ITMP1);
677 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
678 M_IADD(s1, REG_ZERO, d);
679 store_reg_to_var_int(iptr->dst, d);
682 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
684 var_to_reg_int(s1, src, REG_ITMP1);
685 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
686 if (has_ext_instr_set) {
689 M_SLL_IMM(s1, 56, d);
690 M_SRA_IMM( d, 56, d);
692 store_reg_to_var_int(iptr->dst, d);
695 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
697 var_to_reg_int(s1, src, REG_ITMP1);
698 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
700 store_reg_to_var_int(iptr->dst, d);
703 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
705 var_to_reg_int(s1, src, REG_ITMP1);
706 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
707 if (has_ext_instr_set) {
710 M_SLL_IMM(s1, 48, d);
711 M_SRA_IMM( d, 48, d);
713 store_reg_to_var_int(iptr->dst, d);
717 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
719 var_to_reg_int(s1, src->prev, REG_ITMP1);
720 var_to_reg_int(s2, src, REG_ITMP2);
721 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
723 store_reg_to_var_int(iptr->dst, d);
726 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
727 /* val.i = constant */
729 var_to_reg_int(s1, src, REG_ITMP1);
730 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
731 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
732 M_IADD_IMM(s1, iptr->val.i, d);
734 ICONST(REG_ITMP2, iptr->val.i);
735 M_IADD(s1, REG_ITMP2, d);
737 store_reg_to_var_int(iptr->dst, d);
740 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
742 var_to_reg_int(s1, src->prev, REG_ITMP1);
743 var_to_reg_int(s2, src, REG_ITMP2);
744 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
746 store_reg_to_var_int(iptr->dst, d);
749 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
750 /* val.l = constant */
752 var_to_reg_int(s1, src, REG_ITMP1);
753 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
754 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
755 M_LADD_IMM(s1, iptr->val.l, d);
757 LCONST(REG_ITMP2, iptr->val.l);
758 M_LADD(s1, REG_ITMP2, d);
760 store_reg_to_var_int(iptr->dst, d);
763 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
765 var_to_reg_int(s1, src->prev, REG_ITMP1);
766 var_to_reg_int(s2, src, REG_ITMP2);
767 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
769 store_reg_to_var_int(iptr->dst, d);
772 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
773 /* val.i = constant */
775 var_to_reg_int(s1, src, REG_ITMP1);
776 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
777 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
778 M_ISUB_IMM(s1, iptr->val.i, d);
780 ICONST(REG_ITMP2, iptr->val.i);
781 M_ISUB(s1, REG_ITMP2, d);
783 store_reg_to_var_int(iptr->dst, d);
786 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
788 var_to_reg_int(s1, src->prev, REG_ITMP1);
789 var_to_reg_int(s2, src, REG_ITMP2);
790 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
792 store_reg_to_var_int(iptr->dst, d);
795 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
796 /* val.l = constant */
798 var_to_reg_int(s1, src, REG_ITMP1);
799 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
800 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
801 M_LSUB_IMM(s1, iptr->val.l, d);
803 LCONST(REG_ITMP2, iptr->val.l);
804 M_LSUB(s1, REG_ITMP2, d);
806 store_reg_to_var_int(iptr->dst, d);
809 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
811 var_to_reg_int(s1, src->prev, REG_ITMP1);
812 var_to_reg_int(s2, src, REG_ITMP2);
813 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
815 store_reg_to_var_int(iptr->dst, d);
818 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
819 /* val.i = constant */
821 var_to_reg_int(s1, src, REG_ITMP1);
822 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
823 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
824 M_IMUL_IMM(s1, iptr->val.i, d);
826 ICONST(REG_ITMP2, iptr->val.i);
827 M_IMUL(s1, REG_ITMP2, d);
829 store_reg_to_var_int(iptr->dst, d);
832 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
834 var_to_reg_int(s1, src->prev, REG_ITMP1);
835 var_to_reg_int(s2, src, REG_ITMP2);
836 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
838 store_reg_to_var_int(iptr->dst, d);
841 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
842 /* val.l = constant */
844 var_to_reg_int(s1, src, REG_ITMP1);
845 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
846 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
847 M_LMUL_IMM(s1, iptr->val.l, d);
849 LCONST(REG_ITMP2, iptr->val.l);
850 M_LMUL(s1, REG_ITMP2, d);
852 store_reg_to_var_int(iptr->dst, d);
855 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
856 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
858 var_to_reg_int(s1, src->prev, REG_ITMP1);
859 var_to_reg_int(s2, src, REG_ITMP2);
860 d = reg_of_var(rd, iptr->dst, REG_RESULT);
862 codegen_addxdivrefs(cd, mcodeptr);
864 M_MOV(s1, rd->argintregs[0]);
865 M_MOV(s2, rd->argintregs[1]);
867 disp = dseg_addaddress(cd, bte->fp);
868 M_ALD(REG_PV, REG_PV, disp);
869 M_JSR(REG_RA, REG_PV);
870 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
871 M_LDA(REG_PV, REG_RA, -disp);
873 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
874 store_reg_to_var_int(iptr->dst, d);
877 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
878 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
880 var_to_reg_int(s1, src->prev, REG_ITMP1);
881 var_to_reg_int(s2, src, REG_ITMP2);
882 d = reg_of_var(rd, iptr->dst, REG_RESULT);
884 codegen_addxdivrefs(cd, mcodeptr);
886 M_MOV(s1, rd->argintregs[0]);
887 M_MOV(s2, rd->argintregs[1]);
889 disp = dseg_addaddress(cd, bte->fp);
890 M_ALD(REG_PV, REG_PV, disp);
891 M_JSR(REG_RA, REG_PV);
892 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
893 M_LDA(REG_PV, REG_RA, -disp);
895 M_INTMOVE(REG_RESULT, d);
896 store_reg_to_var_int(iptr->dst, d);
899 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
900 case ICMD_LDIVPOW2: /* val.i = constant */
902 var_to_reg_int(s1, src, REG_ITMP1);
903 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
904 if (iptr->val.i <= 15) {
905 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
906 M_CMOVGE(s1, s1, REG_ITMP2);
908 M_SRA_IMM(s1, 63, REG_ITMP2);
909 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
910 M_LADD(s1, REG_ITMP2, REG_ITMP2);
912 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
913 store_reg_to_var_int(iptr->dst, d);
916 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
918 var_to_reg_int(s1, src->prev, REG_ITMP1);
919 var_to_reg_int(s2, src, REG_ITMP2);
920 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
921 M_AND_IMM(s2, 0x1f, REG_ITMP3);
922 M_SLL(s1, REG_ITMP3, d);
923 M_IADD(d, REG_ZERO, d);
924 store_reg_to_var_int(iptr->dst, d);
927 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
928 /* val.i = constant */
930 var_to_reg_int(s1, src, REG_ITMP1);
931 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
932 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
933 M_IADD(d, REG_ZERO, d);
934 store_reg_to_var_int(iptr->dst, d);
937 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
939 var_to_reg_int(s1, src->prev, REG_ITMP1);
940 var_to_reg_int(s2, src, REG_ITMP2);
941 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
942 M_AND_IMM(s2, 0x1f, REG_ITMP3);
943 M_SRA(s1, REG_ITMP3, d);
944 store_reg_to_var_int(iptr->dst, d);
947 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
948 /* val.i = constant */
950 var_to_reg_int(s1, src, REG_ITMP1);
951 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
952 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
953 store_reg_to_var_int(iptr->dst, d);
956 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
958 var_to_reg_int(s1, src->prev, REG_ITMP1);
959 var_to_reg_int(s2, src, REG_ITMP2);
960 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
961 M_AND_IMM(s2, 0x1f, REG_ITMP2);
963 M_SRL(d, REG_ITMP2, d);
964 M_IADD(d, REG_ZERO, d);
965 store_reg_to_var_int(iptr->dst, d);
968 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
969 /* val.i = constant */
971 var_to_reg_int(s1, src, REG_ITMP1);
972 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
974 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
975 M_IADD(d, REG_ZERO, d);
976 store_reg_to_var_int(iptr->dst, d);
979 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
981 var_to_reg_int(s1, src->prev, REG_ITMP1);
982 var_to_reg_int(s2, src, REG_ITMP2);
983 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
985 store_reg_to_var_int(iptr->dst, d);
988 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
989 /* val.i = constant */
991 var_to_reg_int(s1, src, REG_ITMP1);
992 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
993 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
994 store_reg_to_var_int(iptr->dst, d);
997 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
999 var_to_reg_int(s1, src->prev, REG_ITMP1);
1000 var_to_reg_int(s2, src, REG_ITMP2);
1001 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1003 store_reg_to_var_int(iptr->dst, d);
1006 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1007 /* val.i = constant */
1009 var_to_reg_int(s1, src, REG_ITMP1);
1010 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1011 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1012 store_reg_to_var_int(iptr->dst, d);
1015 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1017 var_to_reg_int(s1, src->prev, REG_ITMP1);
1018 var_to_reg_int(s2, src, REG_ITMP2);
1019 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1021 store_reg_to_var_int(iptr->dst, d);
1024 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1025 /* val.i = constant */
1027 var_to_reg_int(s1, src, REG_ITMP1);
1028 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1029 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1030 store_reg_to_var_int(iptr->dst, d);
1033 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1036 var_to_reg_int(s1, src->prev, REG_ITMP1);
1037 var_to_reg_int(s2, src, REG_ITMP2);
1038 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1040 store_reg_to_var_int(iptr->dst, d);
1043 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1044 /* val.i = constant */
1046 var_to_reg_int(s1, src, REG_ITMP1);
1047 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1048 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1049 M_AND_IMM(s1, iptr->val.i, d);
1050 } else if (iptr->val.i == 0xffff) {
1052 } else if (iptr->val.i == 0xffffff) {
1053 M_ZAPNOT_IMM(s1, 0x07, d);
1055 ICONST(REG_ITMP2, iptr->val.i);
1056 M_AND(s1, REG_ITMP2, d);
1058 store_reg_to_var_int(iptr->dst, d);
1061 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1062 /* val.i = constant */
1064 var_to_reg_int(s1, src, REG_ITMP1);
1065 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1067 M_MOV(s1, REG_ITMP1);
1070 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1071 M_AND_IMM(s1, iptr->val.i, d);
1073 M_ISUB(REG_ZERO, s1, d);
1074 M_AND_IMM(d, iptr->val.i, d);
1075 } else if (iptr->val.i == 0xffff) {
1078 M_ISUB(REG_ZERO, s1, d);
1080 } else if (iptr->val.i == 0xffffff) {
1081 M_ZAPNOT_IMM(s1, 0x07, d);
1083 M_ISUB(REG_ZERO, s1, d);
1084 M_ZAPNOT_IMM(d, 0x07, d);
1086 ICONST(REG_ITMP2, iptr->val.i);
1087 M_AND(s1, REG_ITMP2, d);
1089 M_ISUB(REG_ZERO, s1, d);
1090 M_AND(d, REG_ITMP2, d);
1092 M_ISUB(REG_ZERO, d, d);
1093 store_reg_to_var_int(iptr->dst, d);
1096 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1097 /* val.l = constant */
1099 var_to_reg_int(s1, src, REG_ITMP1);
1100 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1101 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1102 M_AND_IMM(s1, iptr->val.l, d);
1103 } else if (iptr->val.l == 0xffffL) {
1105 } else if (iptr->val.l == 0xffffffL) {
1106 M_ZAPNOT_IMM(s1, 0x07, d);
1107 } else if (iptr->val.l == 0xffffffffL) {
1109 } else if (iptr->val.l == 0xffffffffffL) {
1110 M_ZAPNOT_IMM(s1, 0x1f, d);
1111 } else if (iptr->val.l == 0xffffffffffffL) {
1112 M_ZAPNOT_IMM(s1, 0x3f, d);
1113 } else if (iptr->val.l == 0xffffffffffffffL) {
1114 M_ZAPNOT_IMM(s1, 0x7f, d);
1116 LCONST(REG_ITMP2, iptr->val.l);
1117 M_AND(s1, REG_ITMP2, d);
1119 store_reg_to_var_int(iptr->dst, d);
1122 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1123 /* val.l = constant */
1125 var_to_reg_int(s1, src, REG_ITMP1);
1126 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1128 M_MOV(s1, REG_ITMP1);
1131 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1132 M_AND_IMM(s1, iptr->val.l, d);
1134 M_LSUB(REG_ZERO, s1, d);
1135 M_AND_IMM(d, iptr->val.l, d);
1136 } else if (iptr->val.l == 0xffffL) {
1139 M_LSUB(REG_ZERO, s1, d);
1141 } else if (iptr->val.l == 0xffffffL) {
1142 M_ZAPNOT_IMM(s1, 0x07, d);
1144 M_LSUB(REG_ZERO, s1, d);
1145 M_ZAPNOT_IMM(d, 0x07, d);
1146 } else if (iptr->val.l == 0xffffffffL) {
1149 M_LSUB(REG_ZERO, s1, d);
1151 } else if (iptr->val.l == 0xffffffffffL) {
1152 M_ZAPNOT_IMM(s1, 0x1f, d);
1154 M_LSUB(REG_ZERO, s1, d);
1155 M_ZAPNOT_IMM(d, 0x1f, d);
1156 } else if (iptr->val.l == 0xffffffffffffL) {
1157 M_ZAPNOT_IMM(s1, 0x3f, d);
1159 M_LSUB(REG_ZERO, s1, d);
1160 M_ZAPNOT_IMM(d, 0x3f, d);
1161 } else if (iptr->val.l == 0xffffffffffffffL) {
1162 M_ZAPNOT_IMM(s1, 0x7f, d);
1164 M_LSUB(REG_ZERO, s1, d);
1165 M_ZAPNOT_IMM(d, 0x7f, d);
1167 LCONST(REG_ITMP2, iptr->val.l);
1168 M_AND(s1, REG_ITMP2, d);
1170 M_LSUB(REG_ZERO, s1, d);
1171 M_AND(d, REG_ITMP2, d);
1173 M_LSUB(REG_ZERO, d, d);
1174 store_reg_to_var_int(iptr->dst, d);
1177 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1180 var_to_reg_int(s1, src->prev, REG_ITMP1);
1181 var_to_reg_int(s2, src, REG_ITMP2);
1182 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1184 store_reg_to_var_int(iptr->dst, d);
1187 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1188 /* val.i = constant */
1190 var_to_reg_int(s1, src, REG_ITMP1);
1191 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1192 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1193 M_OR_IMM(s1, iptr->val.i, d);
1195 ICONST(REG_ITMP2, iptr->val.i);
1196 M_OR(s1, REG_ITMP2, d);
1198 store_reg_to_var_int(iptr->dst, d);
1201 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1202 /* val.l = constant */
1204 var_to_reg_int(s1, src, REG_ITMP1);
1205 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1206 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1207 M_OR_IMM(s1, iptr->val.l, d);
1209 LCONST(REG_ITMP2, iptr->val.l);
1210 M_OR(s1, REG_ITMP2, d);
1212 store_reg_to_var_int(iptr->dst, d);
1215 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1218 var_to_reg_int(s1, src->prev, REG_ITMP1);
1219 var_to_reg_int(s2, src, REG_ITMP2);
1220 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1222 store_reg_to_var_int(iptr->dst, d);
1225 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1226 /* val.i = constant */
1228 var_to_reg_int(s1, src, REG_ITMP1);
1229 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1230 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1231 M_XOR_IMM(s1, iptr->val.i, d);
1233 ICONST(REG_ITMP2, iptr->val.i);
1234 M_XOR(s1, REG_ITMP2, d);
1236 store_reg_to_var_int(iptr->dst, d);
1239 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1240 /* val.l = constant */
1242 var_to_reg_int(s1, src, REG_ITMP1);
1243 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1244 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1245 M_XOR_IMM(s1, iptr->val.l, d);
1247 LCONST(REG_ITMP2, iptr->val.l);
1248 M_XOR(s1, REG_ITMP2, d);
1250 store_reg_to_var_int(iptr->dst, d);
1254 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1256 var_to_reg_int(s1, src->prev, REG_ITMP1);
1257 var_to_reg_int(s2, src, REG_ITMP2);
1258 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1259 M_CMPLT(s1, s2, REG_ITMP3);
1260 M_CMPLT(s2, s1, REG_ITMP1);
1261 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1262 store_reg_to_var_int(iptr->dst, d);
1266 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1267 /* op1 = variable, val.i = constant */
1269 var = &(rd->locals[iptr->op1][TYPE_INT]);
1270 if (var->flags & INMEMORY) {
1272 M_LLD(s1, REG_SP, var->regoff * 8);
1275 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1276 M_IADD_IMM(s1, iptr->val.i, s1);
1277 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1278 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1280 M_LDA (s1, s1, iptr->val.i);
1281 M_IADD(s1, REG_ZERO, s1);
1283 if (var->flags & INMEMORY)
1284 M_LST(s1, REG_SP, var->regoff * 8);
1288 /* floating operations ************************************************/
1290 case ICMD_FNEG: /* ..., value ==> ..., - value */
1292 var_to_reg_flt(s1, src, REG_FTMP1);
1293 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1295 store_reg_to_var_flt(iptr->dst, d);
1298 case ICMD_DNEG: /* ..., value ==> ..., - value */
1300 var_to_reg_flt(s1, src, REG_FTMP1);
1301 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1303 store_reg_to_var_flt(iptr->dst, d);
1306 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1308 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1309 var_to_reg_flt(s2, src, REG_FTMP2);
1310 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1314 if (d == s1 || d == s2) {
1315 M_FADDS(s1, s2, REG_FTMP3);
1317 M_FMOV(REG_FTMP3, d);
1323 store_reg_to_var_flt(iptr->dst, d);
1326 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1328 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1329 var_to_reg_flt(s2, src, REG_FTMP2);
1330 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1334 if (d == s1 || d == s2) {
1335 M_DADDS(s1, s2, REG_FTMP3);
1337 M_FMOV(REG_FTMP3, d);
1343 store_reg_to_var_flt(iptr->dst, d);
1346 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1348 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1349 var_to_reg_flt(s2, src, REG_FTMP2);
1350 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1354 if (d == s1 || d == s2) {
1355 M_FSUBS(s1, s2, REG_FTMP3);
1357 M_FMOV(REG_FTMP3, d);
1363 store_reg_to_var_flt(iptr->dst, d);
1366 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1368 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1369 var_to_reg_flt(s2, src, REG_FTMP2);
1370 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1374 if (d == s1 || d == s2) {
1375 M_DSUBS(s1, s2, REG_FTMP3);
1377 M_FMOV(REG_FTMP3, d);
1383 store_reg_to_var_flt(iptr->dst, d);
1386 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1388 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1389 var_to_reg_flt(s2, src, REG_FTMP2);
1390 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1394 if (d == s1 || d == s2) {
1395 M_FMULS(s1, s2, REG_FTMP3);
1397 M_FMOV(REG_FTMP3, d);
1403 store_reg_to_var_flt(iptr->dst, d);
1406 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1408 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1409 var_to_reg_flt(s2, src, REG_FTMP2);
1410 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1414 if (d == s1 || d == s2) {
1415 M_DMULS(s1, s2, REG_FTMP3);
1417 M_FMOV(REG_FTMP3, d);
1423 store_reg_to_var_flt(iptr->dst, d);
1426 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1428 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1429 var_to_reg_flt(s2, src, REG_FTMP2);
1430 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1434 if (d == s1 || d == s2) {
1435 M_FDIVS(s1, s2, REG_FTMP3);
1437 M_FMOV(REG_FTMP3, d);
1443 store_reg_to_var_flt(iptr->dst, d);
1446 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1448 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1449 var_to_reg_flt(s2, src, REG_FTMP2);
1450 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1454 if (d == s1 || d == s2) {
1455 M_DDIVS(s1, s2, REG_FTMP3);
1457 M_FMOV(REG_FTMP3, d);
1463 store_reg_to_var_flt(iptr->dst, d);
1466 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1468 var_to_reg_int(s1, src, REG_ITMP1);
1469 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1470 disp = dseg_adddouble(cd, 0.0);
1471 M_LST(s1, REG_PV, disp);
1472 M_DLD(d, REG_PV, disp);
1474 store_reg_to_var_flt(iptr->dst, d);
1477 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1479 var_to_reg_int(s1, src, REG_ITMP1);
1480 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1481 disp = dseg_adddouble(cd, 0.0);
1482 M_LST(s1, REG_PV, disp);
1483 M_DLD(d, REG_PV, disp);
1485 store_reg_to_var_flt(iptr->dst, d);
1488 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1490 var_to_reg_flt(s1, src, REG_FTMP1);
1491 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1492 disp = dseg_adddouble(cd, 0.0);
1493 M_CVTDL_C(s1, REG_FTMP2);
1494 M_CVTLI(REG_FTMP2, REG_FTMP3);
1495 M_DST(REG_FTMP3, REG_PV, disp);
1496 M_ILD(d, REG_PV, disp);
1497 store_reg_to_var_int(iptr->dst, d);
1500 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1502 var_to_reg_flt(s1, src, REG_FTMP1);
1503 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1504 disp = dseg_adddouble(cd, 0.0);
1505 M_CVTDL_C(s1, REG_FTMP2);
1506 M_DST(REG_FTMP2, REG_PV, disp);
1507 M_LLD(d, REG_PV, disp);
1508 store_reg_to_var_int(iptr->dst, d);
1511 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1513 var_to_reg_flt(s1, src, REG_FTMP1);
1514 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1517 store_reg_to_var_flt(iptr->dst, d);
1520 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1522 var_to_reg_flt(s1, src, REG_FTMP1);
1523 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1530 store_reg_to_var_flt(iptr->dst, d);
1533 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1535 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1536 var_to_reg_flt(s2, src, REG_FTMP2);
1537 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1539 M_LSUB_IMM(REG_ZERO, 1, d);
1540 M_FCMPEQ(s1, s2, REG_FTMP3);
1541 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1543 M_FCMPLT(s2, s1, REG_FTMP3);
1544 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1545 M_LADD_IMM(REG_ZERO, 1, d);
1547 M_LSUB_IMM(REG_ZERO, 1, d);
1548 M_FCMPEQS(s1, s2, REG_FTMP3);
1550 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1552 M_FCMPLTS(s2, s1, REG_FTMP3);
1554 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1555 M_LADD_IMM(REG_ZERO, 1, d);
1557 store_reg_to_var_int(iptr->dst, d);
1560 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1562 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1563 var_to_reg_flt(s2, src, REG_FTMP2);
1564 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1566 M_LADD_IMM(REG_ZERO, 1, d);
1567 M_FCMPEQ(s1, s2, REG_FTMP3);
1568 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1570 M_FCMPLT(s1, s2, REG_FTMP3);
1571 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1572 M_LSUB_IMM(REG_ZERO, 1, d);
1574 M_LADD_IMM(REG_ZERO, 1, d);
1575 M_FCMPEQS(s1, s2, REG_FTMP3);
1577 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1579 M_FCMPLTS(s1, s2, REG_FTMP3);
1581 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1582 M_LSUB_IMM(REG_ZERO, 1, d);
1584 store_reg_to_var_int(iptr->dst, d);
1588 /* memory operations **************************************************/
1590 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1592 var_to_reg_int(s1, src, REG_ITMP1);
1593 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1594 gen_nullptr_check(s1);
1595 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1596 store_reg_to_var_int(iptr->dst, d);
1599 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1601 var_to_reg_int(s1, src->prev, REG_ITMP1);
1602 var_to_reg_int(s2, src, REG_ITMP2);
1603 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1604 if (iptr->op1 == 0) {
1605 gen_nullptr_check(s1);
1608 if (has_ext_instr_set) {
1609 M_LADD (s2, s1, REG_ITMP1);
1610 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1613 M_LADD(s2, s1, REG_ITMP1);
1614 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1615 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1616 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1617 M_SRA_IMM(d, 56, d);
1619 store_reg_to_var_int(iptr->dst, d);
1622 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1624 var_to_reg_int(s1, src->prev, REG_ITMP1);
1625 var_to_reg_int(s2, src, REG_ITMP2);
1626 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1627 if (iptr->op1 == 0) {
1628 gen_nullptr_check(s1);
1631 if (has_ext_instr_set) {
1632 M_LADD(s2, s1, REG_ITMP1);
1633 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1634 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1636 M_LADD (s2, s1, REG_ITMP1);
1637 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1638 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1639 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1640 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1642 store_reg_to_var_int(iptr->dst, d);
1645 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1647 var_to_reg_int(s1, src->prev, REG_ITMP1);
1648 var_to_reg_int(s2, src, REG_ITMP2);
1649 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1650 if (iptr->op1 == 0) {
1651 gen_nullptr_check(s1);
1654 if (has_ext_instr_set) {
1655 M_LADD(s2, s1, REG_ITMP1);
1656 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1657 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1660 M_LADD(s2, s1, REG_ITMP1);
1661 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1662 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1663 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1664 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1665 M_SRA_IMM(d, 48, d);
1667 store_reg_to_var_int(iptr->dst, d);
1670 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1672 var_to_reg_int(s1, src->prev, REG_ITMP1);
1673 var_to_reg_int(s2, src, REG_ITMP2);
1674 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1675 if (iptr->op1 == 0) {
1676 gen_nullptr_check(s1);
1679 M_S4ADDQ(s2, s1, REG_ITMP1);
1680 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1681 store_reg_to_var_int(iptr->dst, d);
1684 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1686 var_to_reg_int(s1, src->prev, REG_ITMP1);
1687 var_to_reg_int(s2, src, REG_ITMP2);
1688 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1689 if (iptr->op1 == 0) {
1690 gen_nullptr_check(s1);
1693 M_S8ADDQ(s2, s1, REG_ITMP1);
1694 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1695 store_reg_to_var_int(iptr->dst, d);
1698 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1700 var_to_reg_int(s1, src->prev, REG_ITMP1);
1701 var_to_reg_int(s2, src, REG_ITMP2);
1702 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1703 if (iptr->op1 == 0) {
1704 gen_nullptr_check(s1);
1707 M_S4ADDQ(s2, s1, REG_ITMP1);
1708 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1709 store_reg_to_var_flt(iptr->dst, d);
1712 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1714 var_to_reg_int(s1, src->prev, REG_ITMP1);
1715 var_to_reg_int(s2, src, REG_ITMP2);
1716 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1717 if (iptr->op1 == 0) {
1718 gen_nullptr_check(s1);
1721 M_S8ADDQ(s2, s1, REG_ITMP1);
1722 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1723 store_reg_to_var_flt(iptr->dst, d);
1726 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1728 var_to_reg_int(s1, src->prev, REG_ITMP1);
1729 var_to_reg_int(s2, src, REG_ITMP2);
1730 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1731 if (iptr->op1 == 0) {
1732 gen_nullptr_check(s1);
1735 M_SAADDQ(s2, s1, REG_ITMP1);
1736 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1737 store_reg_to_var_int(iptr->dst, d);
1741 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1743 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1744 var_to_reg_int(s2, src->prev, REG_ITMP2);
1745 if (iptr->op1 == 0) {
1746 gen_nullptr_check(s1);
1749 var_to_reg_int(s3, src, REG_ITMP3);
1750 if (has_ext_instr_set) {
1751 M_LADD(s2, s1, REG_ITMP1);
1752 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1754 M_LADD(s2, s1, REG_ITMP1);
1755 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1756 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1757 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1758 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1759 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1760 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1764 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1766 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1767 var_to_reg_int(s2, src->prev, REG_ITMP2);
1768 if (iptr->op1 == 0) {
1769 gen_nullptr_check(s1);
1772 var_to_reg_int(s3, src, REG_ITMP3);
1773 if (has_ext_instr_set) {
1774 M_LADD(s2, s1, REG_ITMP1);
1775 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1776 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1778 M_LADD(s2, s1, REG_ITMP1);
1779 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1780 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1781 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1782 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1783 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1784 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1785 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1789 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1791 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1792 var_to_reg_int(s2, src->prev, REG_ITMP2);
1793 if (iptr->op1 == 0) {
1794 gen_nullptr_check(s1);
1797 var_to_reg_int(s3, src, REG_ITMP3);
1798 if (has_ext_instr_set) {
1799 M_LADD(s2, s1, REG_ITMP1);
1800 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1801 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1803 M_LADD(s2, s1, REG_ITMP1);
1804 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1805 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1806 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1807 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1808 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1809 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1810 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1814 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1816 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1817 var_to_reg_int(s2, src->prev, REG_ITMP2);
1818 if (iptr->op1 == 0) {
1819 gen_nullptr_check(s1);
1822 var_to_reg_int(s3, src, REG_ITMP3);
1823 M_S4ADDQ(s2, s1, REG_ITMP1);
1824 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1827 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1829 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1830 var_to_reg_int(s2, src->prev, REG_ITMP2);
1831 if (iptr->op1 == 0) {
1832 gen_nullptr_check(s1);
1835 var_to_reg_int(s3, src, REG_ITMP3);
1836 M_S8ADDQ(s2, s1, REG_ITMP1);
1837 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1840 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1842 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1843 var_to_reg_int(s2, src->prev, REG_ITMP2);
1844 if (iptr->op1 == 0) {
1845 gen_nullptr_check(s1);
1848 var_to_reg_flt(s3, src, REG_FTMP3);
1849 M_S4ADDQ(s2, s1, REG_ITMP1);
1850 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1853 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1855 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1856 var_to_reg_int(s2, src->prev, REG_ITMP2);
1857 if (iptr->op1 == 0) {
1858 gen_nullptr_check(s1);
1861 var_to_reg_flt(s3, src, REG_FTMP3);
1862 M_S8ADDQ(s2, s1, REG_ITMP1);
1863 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1866 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1868 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1869 var_to_reg_int(s2, src->prev, REG_ITMP2);
1870 /* if (iptr->op1 == 0) { */
1871 gen_nullptr_check(s1);
1874 var_to_reg_int(s3, src, REG_ITMP3);
1876 M_MOV(s1, rd->argintregs[0]);
1877 M_MOV(s3, rd->argintregs[1]);
1879 disp = dseg_addaddress(cd, bte->fp);
1880 M_ALD(REG_PV, REG_PV, disp);
1881 M_JSR(REG_RA, REG_PV);
1882 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1883 M_LDA(REG_PV, REG_RA, -disp);
1885 M_BEQZ(REG_RESULT, 0);
1886 codegen_addxstorerefs(cd, mcodeptr);
1888 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1889 var_to_reg_int(s2, src->prev, REG_ITMP2);
1890 var_to_reg_int(s3, src, REG_ITMP3);
1891 M_SAADDQ(s2, s1, REG_ITMP1);
1892 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1896 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1898 var_to_reg_int(s1, src->prev, REG_ITMP1);
1899 var_to_reg_int(s2, src, REG_ITMP2);
1900 if (iptr->op1 == 0) {
1901 gen_nullptr_check(s1);
1904 M_S4ADDQ(s2, s1, REG_ITMP1);
1905 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1908 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1910 var_to_reg_int(s1, src->prev, REG_ITMP1);
1911 var_to_reg_int(s2, src, REG_ITMP2);
1912 if (iptr->op1 == 0) {
1913 gen_nullptr_check(s1);
1916 M_S8ADDQ(s2, s1, REG_ITMP1);
1917 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1920 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1922 var_to_reg_int(s1, src->prev, REG_ITMP1);
1923 var_to_reg_int(s2, src, REG_ITMP2);
1924 if (iptr->op1 == 0) {
1925 gen_nullptr_check(s1);
1928 M_SAADDQ(s2, s1, REG_ITMP1);
1929 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1932 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1934 var_to_reg_int(s1, src->prev, REG_ITMP1);
1935 var_to_reg_int(s2, src, REG_ITMP2);
1936 if (iptr->op1 == 0) {
1937 gen_nullptr_check(s1);
1940 if (has_ext_instr_set) {
1941 M_LADD(s2, s1, REG_ITMP1);
1942 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1945 M_LADD(s2, s1, REG_ITMP1);
1946 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1947 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1948 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1949 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1950 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1951 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1955 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1957 var_to_reg_int(s1, src->prev, REG_ITMP1);
1958 var_to_reg_int(s2, src, REG_ITMP2);
1959 if (iptr->op1 == 0) {
1960 gen_nullptr_check(s1);
1963 if (has_ext_instr_set) {
1964 M_LADD(s2, s1, REG_ITMP1);
1965 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1966 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1969 M_LADD(s2, s1, REG_ITMP1);
1970 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1971 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1972 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1973 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1974 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1975 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1976 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1980 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1982 var_to_reg_int(s1, src->prev, REG_ITMP1);
1983 var_to_reg_int(s2, src, REG_ITMP2);
1984 if (iptr->op1 == 0) {
1985 gen_nullptr_check(s1);
1988 if (has_ext_instr_set) {
1989 M_LADD(s2, s1, REG_ITMP1);
1990 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1991 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1994 M_LADD(s2, s1, REG_ITMP1);
1995 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1996 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1997 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1998 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1999 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2000 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2001 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2006 case ICMD_GETSTATIC: /* ... ==> ..., value */
2007 /* op1 = type, val.a = field address */
2010 disp = dseg_addaddress(cd, 0);
2012 codegen_addpatchref(cd, mcodeptr,
2013 PATCHER_get_putstatic,
2014 (unresolved_field *) iptr->target, disp);
2016 if (opt_showdisassemble)
2021 fieldinfo *fi = iptr->val.a;
2023 disp = dseg_addaddress(cd, &(fi->value));
2025 if (!fi->class->initialized) {
2026 codegen_addpatchref(cd, mcodeptr,
2027 PATCHER_clinit, fi->class, 0);
2029 if (opt_showdisassemble)
2034 M_ALD(REG_ITMP1, REG_PV, disp);
2035 switch (iptr->op1) {
2037 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2038 M_ILD(d, REG_ITMP1, 0);
2039 store_reg_to_var_int(iptr->dst, d);
2042 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2043 M_LLD(d, REG_ITMP1, 0);
2044 store_reg_to_var_int(iptr->dst, d);
2047 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2048 M_ALD(d, REG_ITMP1, 0);
2049 store_reg_to_var_int(iptr->dst, d);
2052 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2053 M_FLD(d, REG_ITMP1, 0);
2054 store_reg_to_var_flt(iptr->dst, d);
2057 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2058 M_DLD(d, REG_ITMP1, 0);
2059 store_reg_to_var_flt(iptr->dst, d);
2064 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2065 /* op1 = type, val.a = field address */
2068 disp = dseg_addaddress(cd, 0);
2070 codegen_addpatchref(cd, mcodeptr,
2071 PATCHER_get_putstatic,
2072 (unresolved_field *) iptr->target, disp);
2074 if (opt_showdisassemble)
2078 fieldinfo *fi = iptr->val.a;
2080 disp = dseg_addaddress(cd, &(fi->value));
2082 if (!fi->class->initialized) {
2083 codegen_addpatchref(cd, mcodeptr,
2084 PATCHER_clinit, fi->class, 0);
2086 if (opt_showdisassemble)
2091 M_ALD(REG_ITMP1, REG_PV, disp);
2092 switch (iptr->op1) {
2094 var_to_reg_int(s2, src, REG_ITMP2);
2095 M_IST(s2, REG_ITMP1, 0);
2098 var_to_reg_int(s2, src, REG_ITMP2);
2099 M_LST(s2, REG_ITMP1, 0);
2102 var_to_reg_int(s2, src, REG_ITMP2);
2103 M_AST(s2, REG_ITMP1, 0);
2106 var_to_reg_flt(s2, src, REG_FTMP2);
2107 M_FST(s2, REG_ITMP1, 0);
2110 var_to_reg_flt(s2, src, REG_FTMP2);
2111 M_DST(s2, REG_ITMP1, 0);
2116 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2117 /* val = value (in current instruction) */
2118 /* op1 = type, val.a = field address (in */
2119 /* following NOP) */
2121 if (!iptr[1].val.a) {
2122 disp = dseg_addaddress(cd, 0);
2124 codegen_addpatchref(cd, mcodeptr,
2125 PATCHER_get_putstatic,
2126 (unresolved_field *) iptr[1].target, disp);
2128 if (opt_showdisassemble)
2132 fieldinfo *fi = iptr[1].val.a;
2134 disp = dseg_addaddress(cd, &(fi->value));
2136 if (!fi->class->initialized) {
2137 codegen_addpatchref(cd, mcodeptr,
2138 PATCHER_clinit, fi->class, 0);
2140 if (opt_showdisassemble)
2145 M_ALD(REG_ITMP1, REG_PV, disp);
2146 switch (iptr->op1) {
2148 M_IST(REG_ZERO, REG_ITMP1, 0);
2151 M_LST(REG_ZERO, REG_ITMP1, 0);
2154 M_AST(REG_ZERO, REG_ITMP1, 0);
2157 M_FST(REG_ZERO, REG_ITMP1, 0);
2160 M_DST(REG_ZERO, REG_ITMP1, 0);
2166 case ICMD_GETFIELD: /* ... ==> ..., value */
2167 /* op1 = type, val.i = field offset */
2169 var_to_reg_int(s1, src, REG_ITMP1);
2170 gen_nullptr_check(s1);
2173 codegen_addpatchref(cd, mcodeptr,
2174 PATCHER_get_putfield,
2175 (unresolved_field *) iptr->target, 0);
2177 if (opt_showdisassemble)
2183 disp = ((fieldinfo *) (iptr->val.a))->offset;
2186 switch (iptr->op1) {
2188 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2190 store_reg_to_var_int(iptr->dst, d);
2193 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2195 store_reg_to_var_int(iptr->dst, d);
2198 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2200 store_reg_to_var_int(iptr->dst, d);
2203 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2205 store_reg_to_var_flt(iptr->dst, d);
2208 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2210 store_reg_to_var_flt(iptr->dst, d);
2215 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2216 /* op1 = type, val.a = field address */
2218 var_to_reg_int(s1, src->prev, REG_ITMP1);
2219 gen_nullptr_check(s1);
2221 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2222 var_to_reg_int(s2, src, REG_ITMP2);
2224 var_to_reg_flt(s2, src, REG_FTMP2);
2228 codegen_addpatchref(cd, mcodeptr,
2229 PATCHER_get_putfield,
2230 (unresolved_field *) iptr->target, 0);
2232 if (opt_showdisassemble)
2238 disp = ((fieldinfo *) (iptr->val.a))->offset;
2241 switch (iptr->op1) {
2243 M_IST(s2, s1, disp);
2246 M_LST(s2, s1, disp);
2249 M_AST(s2, s1, disp);
2252 M_FST(s2, s1, disp);
2255 M_DST(s2, s1, disp);
2260 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2261 /* val = value (in current instruction) */
2262 /* op1 = type, val.a = field address (in */
2263 /* following NOP) */
2265 var_to_reg_int(s1, src, REG_ITMP1);
2266 gen_nullptr_check(s1);
2268 if (!iptr[1].val.a) {
2269 codegen_addpatchref(cd, mcodeptr,
2270 PATCHER_get_putfield,
2271 (unresolved_field *) iptr[1].target, 0);
2273 if (opt_showdisassemble)
2279 disp = ((fieldinfo *) (iptr[1].val.a))->offset;
2282 switch (iptr[1].op1) {
2284 M_IST(REG_ZERO, s1, disp);
2287 M_LST(REG_ZERO, s1, disp);
2290 M_AST(REG_ZERO, s1, disp);
2293 M_FST(REG_ZERO, s1, disp);
2296 M_DST(REG_ZERO, s1, disp);
2302 /* branch operations **************************************************/
2304 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2306 var_to_reg_int(s1, src, REG_ITMP1);
2307 M_INTMOVE(s1, REG_ITMP1_XPTR);
2308 disp = dseg_addaddress(cd, asm_handle_exception);
2309 M_ALD(REG_ITMP2, REG_PV, disp);
2310 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2311 M_NOP; /* nop ensures that XPC is less than the end */
2312 /* of basic block */
2316 case ICMD_GOTO: /* ... ==> ... */
2317 /* op1 = target JavaVM pc */
2319 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2323 case ICMD_JSR: /* ... ==> ... */
2324 /* op1 = target JavaVM pc */
2326 M_BSR(REG_ITMP1, 0);
2327 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2330 case ICMD_RET: /* ... ==> ... */
2331 /* op1 = local variable */
2333 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2334 if (var->flags & INMEMORY) {
2335 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2336 M_RET(REG_ZERO, REG_ITMP1);
2339 M_RET(REG_ZERO, var->regoff);
2343 case ICMD_IFNULL: /* ..., value ==> ... */
2344 /* op1 = target JavaVM pc */
2346 var_to_reg_int(s1, src, REG_ITMP1);
2348 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2351 case ICMD_IFNONNULL: /* ..., value ==> ... */
2352 /* op1 = target JavaVM pc */
2354 var_to_reg_int(s1, src, REG_ITMP1);
2356 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2359 case ICMD_IFEQ: /* ..., value ==> ... */
2360 /* op1 = target JavaVM pc, val.i = constant */
2362 var_to_reg_int(s1, src, REG_ITMP1);
2363 if (iptr->val.i == 0) {
2367 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2368 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2371 ICONST(REG_ITMP2, iptr->val.i);
2372 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2374 M_BNEZ(REG_ITMP1, 0);
2376 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2379 case ICMD_IFLT: /* ..., value ==> ... */
2380 /* op1 = target JavaVM pc, val.i = constant */
2382 var_to_reg_int(s1, src, REG_ITMP1);
2383 if (iptr->val.i == 0) {
2387 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2388 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2391 ICONST(REG_ITMP2, iptr->val.i);
2392 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2394 M_BNEZ(REG_ITMP1, 0);
2396 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2399 case ICMD_IFLE: /* ..., value ==> ... */
2400 /* op1 = target JavaVM pc, val.i = constant */
2402 var_to_reg_int(s1, src, REG_ITMP1);
2403 if (iptr->val.i == 0) {
2407 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2408 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2411 ICONST(REG_ITMP2, iptr->val.i);
2412 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2414 M_BNEZ(REG_ITMP1, 0);
2416 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2419 case ICMD_IFNE: /* ..., value ==> ... */
2420 /* op1 = target JavaVM pc, val.i = constant */
2422 var_to_reg_int(s1, src, REG_ITMP1);
2423 if (iptr->val.i == 0) {
2427 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2428 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2431 ICONST(REG_ITMP2, iptr->val.i);
2432 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2434 M_BEQZ(REG_ITMP1, 0);
2436 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2439 case ICMD_IFGT: /* ..., value ==> ... */
2440 /* op1 = target JavaVM pc, val.i = constant */
2442 var_to_reg_int(s1, src, REG_ITMP1);
2443 if (iptr->val.i == 0) {
2447 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2448 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2451 ICONST(REG_ITMP2, iptr->val.i);
2452 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2454 M_BEQZ(REG_ITMP1, 0);
2456 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2459 case ICMD_IFGE: /* ..., value ==> ... */
2460 /* op1 = target JavaVM pc, val.i = constant */
2462 var_to_reg_int(s1, src, REG_ITMP1);
2463 if (iptr->val.i == 0) {
2467 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2468 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2471 ICONST(REG_ITMP2, iptr->val.i);
2472 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2474 M_BEQZ(REG_ITMP1, 0);
2476 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2479 case ICMD_IF_LEQ: /* ..., value ==> ... */
2480 /* op1 = target JavaVM pc, val.l = constant */
2482 var_to_reg_int(s1, src, REG_ITMP1);
2483 if (iptr->val.l == 0) {
2487 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2488 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2491 LCONST(REG_ITMP2, iptr->val.l);
2492 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2494 M_BNEZ(REG_ITMP1, 0);
2496 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2499 case ICMD_IF_LLT: /* ..., value ==> ... */
2500 /* op1 = target JavaVM pc, val.l = constant */
2502 var_to_reg_int(s1, src, REG_ITMP1);
2503 if (iptr->val.l == 0) {
2507 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2508 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2511 LCONST(REG_ITMP2, iptr->val.l);
2512 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2514 M_BNEZ(REG_ITMP1, 0);
2516 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2519 case ICMD_IF_LLE: /* ..., value ==> ... */
2520 /* op1 = target JavaVM pc, val.l = constant */
2522 var_to_reg_int(s1, src, REG_ITMP1);
2523 if (iptr->val.l == 0) {
2527 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2528 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2531 LCONST(REG_ITMP2, iptr->val.l);
2532 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2534 M_BNEZ(REG_ITMP1, 0);
2536 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2539 case ICMD_IF_LNE: /* ..., value ==> ... */
2540 /* op1 = target JavaVM pc, val.l = constant */
2542 var_to_reg_int(s1, src, REG_ITMP1);
2543 if (iptr->val.l == 0) {
2547 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2548 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2551 LCONST(REG_ITMP2, iptr->val.l);
2552 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2554 M_BEQZ(REG_ITMP1, 0);
2556 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2559 case ICMD_IF_LGT: /* ..., value ==> ... */
2560 /* op1 = target JavaVM pc, val.l = constant */
2562 var_to_reg_int(s1, src, REG_ITMP1);
2563 if (iptr->val.l == 0) {
2567 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2568 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2571 LCONST(REG_ITMP2, iptr->val.l);
2572 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2574 M_BEQZ(REG_ITMP1, 0);
2576 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2579 case ICMD_IF_LGE: /* ..., value ==> ... */
2580 /* op1 = target JavaVM pc, val.l = constant */
2582 var_to_reg_int(s1, src, REG_ITMP1);
2583 if (iptr->val.l == 0) {
2587 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2588 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2591 LCONST(REG_ITMP2, iptr->val.l);
2592 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2594 M_BEQZ(REG_ITMP1, 0);
2596 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2599 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2600 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2601 case ICMD_IF_ACMPEQ:
2603 var_to_reg_int(s1, src->prev, REG_ITMP1);
2604 var_to_reg_int(s2, src, REG_ITMP2);
2605 M_CMPEQ(s1, s2, REG_ITMP1);
2606 M_BNEZ(REG_ITMP1, 0);
2607 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2610 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2611 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2612 case ICMD_IF_ACMPNE:
2614 var_to_reg_int(s1, src->prev, REG_ITMP1);
2615 var_to_reg_int(s2, src, REG_ITMP2);
2616 M_CMPEQ(s1, s2, REG_ITMP1);
2617 M_BEQZ(REG_ITMP1, 0);
2618 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2621 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2622 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2624 var_to_reg_int(s1, src->prev, REG_ITMP1);
2625 var_to_reg_int(s2, src, REG_ITMP2);
2626 M_CMPLT(s1, s2, REG_ITMP1);
2627 M_BNEZ(REG_ITMP1, 0);
2628 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2631 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2632 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2634 var_to_reg_int(s1, src->prev, REG_ITMP1);
2635 var_to_reg_int(s2, src, REG_ITMP2);
2636 M_CMPLE(s1, s2, REG_ITMP1);
2637 M_BEQZ(REG_ITMP1, 0);
2638 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2641 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2642 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2644 var_to_reg_int(s1, src->prev, REG_ITMP1);
2645 var_to_reg_int(s2, src, REG_ITMP2);
2646 M_CMPLE(s1, s2, REG_ITMP1);
2647 M_BNEZ(REG_ITMP1, 0);
2648 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2651 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2652 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2654 var_to_reg_int(s1, src->prev, REG_ITMP1);
2655 var_to_reg_int(s2, src, REG_ITMP2);
2656 M_CMPLT(s1, s2, REG_ITMP1);
2657 M_BEQZ(REG_ITMP1, 0);
2658 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2661 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2663 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2666 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2667 /* val.i = constant */
2669 var_to_reg_int(s1, src, REG_ITMP1);
2670 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2672 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2673 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2674 M_CMPEQ(s1, REG_ZERO, d);
2675 store_reg_to_var_int(iptr->dst, d);
2678 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2679 M_CMPEQ(s1, REG_ZERO, d);
2681 store_reg_to_var_int(iptr->dst, d);
2685 M_MOV(s1, REG_ITMP1);
2688 ICONST(d, iptr[1].val.i);
2690 if ((s3 >= 0) && (s3 <= 255)) {
2691 M_CMOVEQ_IMM(s1, s3, d);
2693 ICONST(REG_ITMP2, s3);
2694 M_CMOVEQ(s1, REG_ITMP2, d);
2696 store_reg_to_var_int(iptr->dst, d);
2699 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2700 /* val.i = constant */
2702 var_to_reg_int(s1, src, REG_ITMP1);
2703 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2705 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2706 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2707 M_CMPEQ(s1, REG_ZERO, d);
2708 store_reg_to_var_int(iptr->dst, d);
2711 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2712 M_CMPEQ(s1, REG_ZERO, d);
2714 store_reg_to_var_int(iptr->dst, d);
2718 M_MOV(s1, REG_ITMP1);
2721 ICONST(d, iptr[1].val.i);
2723 if ((s3 >= 0) && (s3 <= 255)) {
2724 M_CMOVNE_IMM(s1, s3, d);
2726 ICONST(REG_ITMP2, s3);
2727 M_CMOVNE(s1, REG_ITMP2, d);
2729 store_reg_to_var_int(iptr->dst, d);
2732 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2733 /* val.i = constant */
2735 var_to_reg_int(s1, src, REG_ITMP1);
2736 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2738 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2739 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2740 M_CMPLT(s1, REG_ZERO, d);
2741 store_reg_to_var_int(iptr->dst, d);
2744 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2745 M_CMPLE(REG_ZERO, s1, d);
2746 store_reg_to_var_int(iptr->dst, d);
2750 M_MOV(s1, REG_ITMP1);
2753 ICONST(d, iptr[1].val.i);
2755 if ((s3 >= 0) && (s3 <= 255)) {
2756 M_CMOVLT_IMM(s1, s3, d);
2758 ICONST(REG_ITMP2, s3);
2759 M_CMOVLT(s1, REG_ITMP2, d);
2761 store_reg_to_var_int(iptr->dst, d);
2764 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2765 /* val.i = constant */
2767 var_to_reg_int(s1, src, REG_ITMP1);
2768 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2770 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2771 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2772 M_CMPLE(REG_ZERO, s1, d);
2773 store_reg_to_var_int(iptr->dst, d);
2776 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2777 M_CMPLT(s1, REG_ZERO, d);
2778 store_reg_to_var_int(iptr->dst, d);
2782 M_MOV(s1, REG_ITMP1);
2785 ICONST(d, iptr[1].val.i);
2787 if ((s3 >= 0) && (s3 <= 255)) {
2788 M_CMOVGE_IMM(s1, s3, d);
2790 ICONST(REG_ITMP2, s3);
2791 M_CMOVGE(s1, REG_ITMP2, d);
2793 store_reg_to_var_int(iptr->dst, d);
2796 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2797 /* val.i = constant */
2799 var_to_reg_int(s1, src, REG_ITMP1);
2800 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2802 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2803 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2804 M_CMPLT(REG_ZERO, s1, d);
2805 store_reg_to_var_int(iptr->dst, d);
2808 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2809 M_CMPLE(s1, REG_ZERO, d);
2810 store_reg_to_var_int(iptr->dst, d);
2814 M_MOV(s1, REG_ITMP1);
2817 ICONST(d, iptr[1].val.i);
2819 if ((s3 >= 0) && (s3 <= 255)) {
2820 M_CMOVGT_IMM(s1, s3, d);
2822 ICONST(REG_ITMP2, s3);
2823 M_CMOVGT(s1, REG_ITMP2, d);
2825 store_reg_to_var_int(iptr->dst, d);
2828 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2829 /* val.i = constant */
2831 var_to_reg_int(s1, src, REG_ITMP1);
2832 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2834 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2835 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2836 M_CMPLE(s1, REG_ZERO, d);
2837 store_reg_to_var_int(iptr->dst, d);
2840 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2841 M_CMPLT(REG_ZERO, s1, d);
2842 store_reg_to_var_int(iptr->dst, d);
2846 M_MOV(s1, REG_ITMP1);
2849 ICONST(d, iptr[1].val.i);
2851 if ((s3 >= 0) && (s3 <= 255)) {
2852 M_CMOVLE_IMM(s1, s3, d);
2854 ICONST(REG_ITMP2, s3);
2855 M_CMOVLE(s1, REG_ITMP2, d);
2857 store_reg_to_var_int(iptr->dst, d);
2861 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2865 var_to_reg_int(s1, src, REG_RESULT);
2866 M_INTMOVE(s1, REG_RESULT);
2868 goto nowperformreturn;
2870 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2873 var_to_reg_flt(s1, src, REG_FRESULT);
2874 M_FLTMOVE(s1, REG_FRESULT);
2876 goto nowperformreturn;
2878 case ICMD_RETURN: /* ... ==> ... */
2884 p = parentargs_base;
2886 /* call trace function */
2889 M_LDA(REG_SP, REG_SP, -3 * 8);
2890 M_AST(REG_RA, REG_SP, 0 * 8);
2891 M_LST(REG_RESULT, REG_SP, 1 * 8);
2892 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2894 disp = dseg_addaddress(cd, m);
2895 M_ALD(rd->argintregs[0], REG_PV, disp);
2896 M_MOV(REG_RESULT, rd->argintregs[1]);
2897 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2898 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2900 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2901 M_ALD(REG_PV, REG_PV, disp);
2902 M_JSR(REG_RA, REG_PV);
2903 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2904 M_LDA(REG_PV, REG_RA, -disp);
2906 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2907 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2908 M_ALD(REG_RA, REG_SP, 0 * 8);
2909 M_LDA(REG_SP, REG_SP, 3 * 8);
2912 #if defined(USE_THREADS)
2913 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2916 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2918 switch (iptr->opc) {
2922 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2926 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2930 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2931 M_ALD(REG_PV, REG_PV, disp);
2932 M_JSR(REG_RA, REG_PV);
2933 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2934 M_LDA(REG_PV, REG_RA, disp);
2936 switch (iptr->opc) {
2940 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2944 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2950 /* restore return address */
2952 if (!m->isleafmethod) {
2953 p--; M_LLD(REG_RA, REG_SP, p * 8);
2956 /* restore saved registers */
2958 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2959 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2961 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2962 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2965 /* deallocate stack */
2967 if (parentargs_base) {
2968 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
2971 M_RET(REG_ZERO, REG_RA);
2977 case ICMD_TABLESWITCH: /* ..., index ==> ... */
2982 tptr = (void **) iptr->target;
2984 s4ptr = iptr->val.a;
2985 l = s4ptr[1]; /* low */
2986 i = s4ptr[2]; /* high */
2988 var_to_reg_int(s1, src, REG_ITMP1);
2990 M_INTMOVE(s1, REG_ITMP1);
2991 } else if (l <= 32768) {
2992 M_LDA(REG_ITMP1, s1, -l);
2994 ICONST(REG_ITMP2, l);
2995 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3002 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3004 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3005 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3007 M_BEQZ(REG_ITMP2, 0);
3008 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3010 /* build jump table top down and use address of lowest entry */
3012 /* s4ptr += 3 + i; */
3016 dseg_addtarget(cd, (basicblock *) tptr[0]);
3021 /* length of dataseg after last dseg_addtarget is used by load */
3023 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3024 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3025 M_JMP(REG_ZERO, REG_ITMP2);
3030 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3032 s4 i, l, val, *s4ptr;
3035 tptr = (void **) iptr->target;
3037 s4ptr = iptr->val.a;
3038 l = s4ptr[0]; /* default */
3039 i = s4ptr[1]; /* count */
3041 MCODECHECK((i<<2)+8);
3042 var_to_reg_int(s1, src, REG_ITMP1);
3048 if ((val >= 0) && (val <= 255)) {
3049 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3051 if ((val >= -32768) && (val <= 32767)) {
3052 M_LDA(REG_ITMP2, REG_ZERO, val);
3054 disp = dseg_adds4(cd, val);
3055 M_ILD(REG_ITMP2, REG_PV, disp);
3057 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3059 M_BNEZ(REG_ITMP2, 0);
3060 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3065 tptr = (void **) iptr->target;
3066 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3073 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3074 /* op1 = arg count val.a = builtintable entry */
3080 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3081 /* op1 = arg count, val.a = method pointer */
3083 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3084 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3085 case ICMD_INVOKEINTERFACE:
3090 md = lm->parseddesc;
3092 unresolved_method *um = iptr->target;
3093 md = um->methodref->parseddesc.md;
3097 s3 = md->paramcount;
3099 MCODECHECK((s3 << 1) + 64);
3101 /* copy arguments to registers or stack location */
3103 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3104 if (src->varkind == ARGVAR)
3106 if (IS_INT_LNG_TYPE(src->type)) {
3107 if (!md->params[s3].inmemory) {
3108 s1 = rd->argintregs[md->params[s3].regoff];
3109 var_to_reg_int(d, src, s1);
3112 var_to_reg_int(d, src, REG_ITMP1);
3113 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3117 if (!md->params[s3].inmemory) {
3118 s1 = rd->argfltregs[md->params[s3].regoff];
3119 var_to_reg_flt(d, src, s1);
3122 var_to_reg_flt(d, src, REG_FTMP1);
3123 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3128 switch (iptr->opc) {
3131 disp = dseg_addaddress(cd, NULL);
3133 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target,
3136 if (opt_showdisassemble)
3140 disp = dseg_addaddress(cd, bte->fp);
3143 d = md->returntype.type;
3145 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3146 M_JSR(REG_RA, REG_PV);
3147 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3148 M_LDA(REG_PV, REG_RA, -disp);
3150 /* if op1 == true, we need to check for an exception */
3152 if (iptr->op1 == true) {
3153 M_BEQZ(REG_RESULT, 0);
3154 codegen_addxexceptionrefs(cd, mcodeptr);
3158 case ICMD_INVOKESPECIAL:
3159 M_BEQZ(rd->argintregs[0], 0);
3160 codegen_addxnullrefs(cd, mcodeptr);
3163 case ICMD_INVOKESTATIC:
3165 unresolved_method *um = iptr->target;
3167 disp = dseg_addaddress(cd, NULL);
3169 codegen_addpatchref(cd, mcodeptr,
3170 PATCHER_invokestatic_special, um, disp);
3172 if (opt_showdisassemble)
3175 d = um->methodref->parseddesc.md->returntype.type;
3178 disp = dseg_addaddress(cd, lm->stubroutine);
3179 d = lm->parseddesc->returntype.type;
3182 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3183 M_JSR(REG_RA, REG_PV);
3184 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3185 M_LDA(REG_PV, REG_RA, -disp);
3188 case ICMD_INVOKEVIRTUAL:
3189 gen_nullptr_check(rd->argintregs[0]);
3192 unresolved_method *um = iptr->target;
3194 codegen_addpatchref(cd, mcodeptr,
3195 PATCHER_invokevirtual, um, 0);
3197 if (opt_showdisassemble)
3201 d = um->methodref->parseddesc.md->returntype.type;
3204 s1 = OFFSET(vftbl_t, table[0]) +
3205 sizeof(methodptr) * lm->vftblindex;
3206 d = lm->parseddesc->returntype.type;
3209 M_ALD(REG_METHODPTR, rd->argintregs[0],
3210 OFFSET(java_objectheader, vftbl));
3211 M_ALD(REG_PV, REG_METHODPTR, s1);
3212 M_JSR(REG_RA, REG_PV);
3213 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3214 M_LDA(REG_PV, REG_RA, -disp);
3217 case ICMD_INVOKEINTERFACE:
3218 gen_nullptr_check(rd->argintregs[0]);
3221 unresolved_method *um = iptr->target;
3223 codegen_addpatchref(cd, mcodeptr,
3224 PATCHER_invokeinterface, um, 0);
3226 if (opt_showdisassemble)
3231 d = um->methodref->parseddesc.md->returntype.type;
3234 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3235 sizeof(methodptr*) * lm->class->index;
3237 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3239 d = lm->parseddesc->returntype.type;
3242 M_ALD(REG_METHODPTR, rd->argintregs[0],
3243 OFFSET(java_objectheader, vftbl));
3244 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3245 M_ALD(REG_PV, REG_METHODPTR, s2);
3246 M_JSR(REG_RA, REG_PV);
3247 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3248 M_LDA(REG_PV, REG_RA, -disp);
3252 /* d contains return type */
3254 if (d != TYPE_VOID) {
3255 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3256 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3257 M_INTMOVE(REG_RESULT, s1);
3258 store_reg_to_var_int(iptr->dst, s1);
3260 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3261 M_FLTMOVE(REG_FRESULT, s1);
3262 store_reg_to_var_flt(iptr->dst, s1);
3268 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3270 /* op1: 0 == array, 1 == class */
3271 /* val.a: (classinfo*) superclass */
3273 /* superclass is an interface:
3275 * OK if ((sub == NULL) ||
3276 * (sub->vftbl->interfacetablelength > super->index) &&
3277 * (sub->vftbl->interfacetable[-super->index] != NULL));
3279 * superclass is a class:
3281 * OK if ((sub == NULL) || (0
3282 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3283 * super->vftbl->diffval));
3288 vftbl_t *supervftbl;
3291 super = (classinfo *) iptr->val.a;
3298 superindex = super->index;
3299 supervftbl = super->vftbl;
3302 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3303 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3305 var_to_reg_int(s1, src, REG_ITMP1);
3307 /* calculate interface checkcast code size */
3311 s2 += opt_showdisassemble ? 1 : 0;
3313 /* calculate class checkcast code size */
3315 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3317 s3 += opt_showdisassemble ? 1 : 0;
3319 /* if class is not resolved, check which code to call */
3322 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3324 disp = dseg_adds4(cd, 0); /* super->flags */
3326 codegen_addpatchref(cd, mcodeptr,
3327 PATCHER_checkcast_instanceof_flags,
3328 (constant_classref *) iptr->target, disp);
3330 if (opt_showdisassemble)
3333 M_ILD(REG_ITMP2, REG_PV, disp);
3334 disp = dseg_adds4(cd, ACC_INTERFACE);
3335 M_ILD(REG_ITMP3, REG_PV, disp);
3336 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3337 M_BEQZ(REG_ITMP2, s2 + 1);
3340 /* interface checkcast code */
3342 if (!super || (super->flags & ACC_INTERFACE)) {
3347 codegen_addpatchref(cd, mcodeptr,
3348 PATCHER_checkcast_instanceof_interface,
3349 (constant_classref *) iptr->target, 0);
3351 if (opt_showdisassemble)
3355 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3356 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3357 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3358 M_BLEZ(REG_ITMP3, 0);
3359 codegen_addxcastrefs(cd, mcodeptr);
3360 M_ALD(REG_ITMP3, REG_ITMP2,
3361 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3362 superindex * sizeof(methodptr*)));
3363 M_BEQZ(REG_ITMP3, 0);
3364 codegen_addxcastrefs(cd, mcodeptr);
3370 /* class checkcast code */
3372 if (!super || !(super->flags & ACC_INTERFACE)) {
3373 disp = dseg_addaddress(cd, supervftbl);
3379 codegen_addpatchref(cd, mcodeptr,
3380 PATCHER_checkcast_instanceof_class,
3381 (constant_classref *) iptr->target,
3384 if (opt_showdisassemble)
3388 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3389 M_ALD(REG_ITMP3, REG_PV, disp);
3390 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3391 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3393 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3394 /* if (s1 != REG_ITMP1) { */
3395 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3396 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3397 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3398 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3400 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3403 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3404 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3405 M_ALD(REG_ITMP3, REG_PV, disp);
3406 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3407 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3408 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3411 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3412 M_BEQZ(REG_ITMP3, 0);
3413 codegen_addxcastrefs(cd, mcodeptr);
3415 d = reg_of_var(rd, iptr->dst, s1);
3417 store_reg_to_var_int(iptr->dst, d);
3421 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
3422 /* op1: 1... resolved, 0... not resolved */
3424 var_to_reg_int(s1, src, rd->argintregs[0]);
3425 M_INTMOVE(s1, rd->argintregs[0]);
3429 disp = dseg_addaddress(cd, iptr->target);
3432 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target, disp);
3434 if (opt_showdisassemble)
3440 a = (ptrint) bte->fp;
3443 M_ALD(rd->argintregs[1], REG_PV, disp);
3445 disp = dseg_addaddress(cd, a);
3446 M_ALD(REG_PV, REG_PV, disp);
3447 M_JSR(REG_RA, REG_PV);
3448 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3449 M_LDA(REG_PV, REG_RA, -disp);
3451 M_BEQZ(REG_RESULT, 0);
3452 codegen_addxcastrefs(cd, mcodeptr);
3454 var_to_reg_int(s1, src, REG_ITMP1);
3455 d = reg_of_var(rd, iptr->dst, s1);
3457 store_reg_to_var_int(iptr->dst, d);
3460 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3462 /* op1: 0 == array, 1 == class */
3463 /* val.a: (classinfo*) superclass */
3465 /* superclass is an interface:
3467 * return (sub != NULL) &&
3468 * (sub->vftbl->interfacetablelength > super->index) &&
3469 * (sub->vftbl->interfacetable[-super->index] != NULL);
3471 * superclass is a class:
3473 * return ((sub != NULL) && (0
3474 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3475 * super->vftbl->diffvall));
3480 vftbl_t *supervftbl;
3483 super = (classinfo *) iptr->val.a;
3490 superindex = super->index;
3491 supervftbl = super->vftbl;
3494 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3495 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3497 var_to_reg_int(s1, src, REG_ITMP1);
3498 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3500 M_MOV(s1, REG_ITMP1);
3504 /* calculate interface instanceof code size */
3508 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3510 /* calculate class instanceof code size */
3514 s3 += (opt_showdisassemble ? 1 : 0);
3516 /* if class is not resolved, check which code to call */
3520 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3522 disp = dseg_adds4(cd, 0); /* super->flags */
3524 codegen_addpatchref(cd, mcodeptr,
3525 PATCHER_checkcast_instanceof_flags,
3526 (constant_classref *) iptr->target, disp);
3528 if (opt_showdisassemble)
3531 M_ILD(REG_ITMP3, REG_PV, disp);
3533 disp = dseg_adds4(cd, ACC_INTERFACE);
3534 M_ILD(REG_ITMP2, REG_PV, disp);
3535 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3536 M_BEQZ(REG_ITMP3, s2 + 1);
3539 /* interface instanceof code */
3541 if (!super || (super->flags & ACC_INTERFACE)) {
3547 /* If d == REG_ITMP2, then it's destroyed in check code */
3552 codegen_addpatchref(cd, mcodeptr,
3553 PATCHER_checkcast_instanceof_interface,
3554 (constant_classref *) iptr->target, 0);
3556 if (opt_showdisassemble)
3560 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3561 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3562 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3563 M_BLEZ(REG_ITMP3, 2);
3564 M_ALD(REG_ITMP1, REG_ITMP1,
3565 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3566 superindex * sizeof(methodptr*)));
3567 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3573 /* class instanceof code */
3575 if (!super || !(super->flags & ACC_INTERFACE)) {
3576 disp = dseg_addaddress(cd, supervftbl);
3583 codegen_addpatchref(cd, mcodeptr,
3584 PATCHER_checkcast_instanceof_class,
3585 (constant_classref *) iptr->target,
3588 if (opt_showdisassemble)
3592 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3593 M_ALD(REG_ITMP2, REG_PV, disp);
3594 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3595 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3597 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3598 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3599 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3600 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3601 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3603 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3604 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3606 store_reg_to_var_int(iptr->dst, d);
3610 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3611 /* op1 = dimension, val.a = array descriptor */
3613 /* check for negative sizes and copy sizes to stack if necessary */
3615 MCODECHECK((iptr->op1 << 1) + 64);
3617 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3618 /* copy SAVEDVAR sizes to stack */
3620 if (src->varkind != ARGVAR) {
3621 var_to_reg_int(s2, src, REG_ITMP1);
3622 M_LST(s2, REG_SP, s1 * 8);
3626 /* a0 = dimension count */
3628 ICONST(rd->argintregs[0], iptr->op1);
3630 /* is patcher function set? */
3633 disp = dseg_addaddress(cd, 0);
3635 codegen_addpatchref(cd, mcodeptr,
3636 (functionptr) iptr->target, iptr->val.a,
3639 if (opt_showdisassemble)
3643 disp = dseg_addaddress(cd, iptr->val.a);
3646 /* a1 = arraydescriptor */
3648 M_ALD(rd->argintregs[1], REG_PV, disp);
3650 /* a2 = pointer to dimensions = stack pointer */
3652 M_INTMOVE(REG_SP, rd->argintregs[2]);
3654 disp = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3655 M_ALD(REG_PV, REG_PV, disp);
3656 M_JSR(REG_RA, REG_PV);
3657 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3658 M_LDA(REG_PV, REG_RA, -disp);
3660 /* check for exception before result assignment */
3662 M_BEQZ(REG_RESULT, 0);
3663 codegen_addxexceptionrefs(cd, mcodeptr);
3665 d = reg_of_var(rd, iptr->dst, REG_RESULT);
3666 M_INTMOVE(REG_RESULT, d);
3667 store_reg_to_var_int(iptr->dst, d);
3671 throw_cacao_exception_exit(string_java_lang_InternalError,
3672 "Unknown ICMD %d", iptr->opc);
3675 } /* for instruction */
3677 /* copy values to interface registers */
3679 src = bptr->outstack;
3680 len = bptr->outdepth;
3687 if ((src->varkind != STACKVAR)) {
3689 if (IS_FLT_DBL_TYPE(s2)) {
3690 var_to_reg_flt(s1, src, REG_FTMP1);
3691 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3692 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3695 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3699 var_to_reg_int(s1, src, REG_ITMP1);
3700 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3701 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3704 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3710 } /* if (bptr -> flags >= BBREACHED) */
3711 } /* for basic block */
3713 codegen_createlinenumbertable(cd);
3717 s4 *xcodeptr = NULL;
3720 /* generate ArithmeticException stubs */
3722 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3723 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3724 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3726 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3730 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3732 (u1 *) mcodeptr - cd->mcodebase);
3736 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3738 if (xcodeptr != NULL) {
3739 disp = xcodeptr - mcodeptr - 1;
3743 xcodeptr = mcodeptr;
3745 M_MOV(REG_PV, rd->argintregs[0]);
3746 M_MOV(REG_SP, rd->argintregs[1]);
3747 M_ALD(rd->argintregs[2],
3748 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3749 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3751 M_LDA(REG_SP, REG_SP, -1 * 8);
3752 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3754 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3755 M_ALD(REG_PV, REG_PV, disp);
3756 M_JSR(REG_RA, REG_PV);
3757 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3758 M_LDA(REG_PV, REG_RA, -disp);
3760 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3762 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3763 M_LDA(REG_SP, REG_SP, 1 * 8);
3765 disp = dseg_addaddress(cd, asm_handle_exception);
3766 M_ALD(REG_ITMP3, REG_PV, disp);
3767 M_JMP(REG_ZERO, REG_ITMP3);
3771 /* generate ArrayIndexOutOfBoundsException stubs */
3775 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3776 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3778 (u1*) mcodeptr - cd->mcodebase);
3782 /* move index register into REG_ITMP1 */
3784 M_MOV(bref->reg, REG_ITMP1);
3785 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3787 if (xcodeptr != NULL) {
3788 disp = xcodeptr - mcodeptr - 1;
3792 xcodeptr = mcodeptr;
3794 M_MOV(REG_PV, rd->argintregs[0]);
3795 M_MOV(REG_SP, rd->argintregs[1]);
3797 if (m->isleafmethod)
3798 M_MOV(REG_RA, rd->argintregs[2]);
3800 M_ALD(rd->argintregs[2],
3801 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3803 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3804 M_MOV(REG_ITMP1, rd->argintregs[4]);
3806 M_LDA(REG_SP, REG_SP, -2 * 8);
3807 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3809 if (m->isleafmethod)
3810 M_AST(REG_RA, REG_SP, 1 * 8);
3812 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3813 M_ALD(REG_PV, REG_PV, disp);
3814 M_JSR(REG_RA, REG_PV);
3815 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3816 M_LDA(REG_PV, REG_RA, -disp);
3818 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3820 if (m->isleafmethod)
3821 M_ALD(REG_RA, REG_SP, 1 * 8);
3823 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3824 M_LDA(REG_SP, REG_SP, 2 * 8);
3826 disp = dseg_addaddress(cd, asm_handle_exception);
3827 M_ALD(REG_ITMP3, REG_PV, disp);
3828 M_JMP(REG_ZERO, REG_ITMP3);
3832 /* generate ArrayStoreException stubs */
3836 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3837 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3838 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3840 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3844 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3846 (u1 *) mcodeptr - cd->mcodebase);
3850 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3852 if (xcodeptr != NULL) {
3853 disp = xcodeptr - mcodeptr - 1;
3857 xcodeptr = mcodeptr;
3859 M_MOV(REG_PV, rd->argintregs[0]);
3860 M_MOV(REG_SP, rd->argintregs[1]);
3861 M_ALD(rd->argintregs[2],
3862 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3863 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3865 M_LDA(REG_SP, REG_SP, -1 * 8);
3866 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3868 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3869 M_ALD(REG_PV, REG_PV, disp);
3870 M_JSR(REG_RA, REG_PV);
3871 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3872 M_LDA(REG_PV, REG_RA, -disp);
3874 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3876 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3877 M_LDA(REG_SP, REG_SP, 1 * 8);
3879 disp = dseg_addaddress(cd, asm_handle_exception);
3880 M_ALD(REG_ITMP3, REG_PV, disp);
3881 M_JMP(REG_ZERO, REG_ITMP3);
3885 /* generate ClassCastException stubs */
3889 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3890 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3891 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3893 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3897 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3899 (u1 *) mcodeptr - cd->mcodebase);
3903 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3905 if (xcodeptr != NULL) {
3906 disp = xcodeptr - mcodeptr - 1;
3910 xcodeptr = mcodeptr;
3912 M_MOV(REG_PV, rd->argintregs[0]);
3913 M_MOV(REG_SP, rd->argintregs[1]);
3915 if (m->isleafmethod)
3916 M_MOV(REG_RA, rd->argintregs[2]);
3918 M_ALD(rd->argintregs[2],
3919 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3921 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3923 M_LDA(REG_SP, REG_SP, -2 * 8);
3924 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3926 if (m->isleafmethod)
3927 M_AST(REG_RA, REG_SP, 1 * 8);
3929 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3930 M_ALD(REG_PV, REG_PV, disp);
3931 M_JSR(REG_RA, REG_PV);
3932 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3933 M_LDA(REG_PV, REG_RA, -disp);
3935 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3937 if (m->isleafmethod)
3938 M_ALD(REG_RA, REG_SP, 1 * 8);
3940 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3941 M_LDA(REG_SP, REG_SP, 2 * 8);
3943 disp = dseg_addaddress(cd, asm_handle_exception);
3944 M_ALD(REG_ITMP3, REG_PV, disp);
3945 M_JMP(REG_ZERO, REG_ITMP3);
3949 /* generate NullPointerException stubs */
3953 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3954 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3955 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3957 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3961 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3963 (u1 *) mcodeptr - cd->mcodebase);
3967 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3969 if (xcodeptr != NULL) {
3970 disp = xcodeptr - mcodeptr - 1;
3974 xcodeptr = mcodeptr;
3976 M_MOV(REG_PV, rd->argintregs[0]);
3977 M_MOV(REG_SP, rd->argintregs[1]);
3979 if (m->isleafmethod)
3980 M_MOV(REG_RA, rd->argintregs[2]);
3982 M_ALD(rd->argintregs[2],
3983 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3985 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3987 M_LDA(REG_SP, REG_SP, -2 * 8);
3988 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3990 if (m->isleafmethod)
3991 M_AST(REG_RA, REG_SP, 1 * 8);
3993 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
3994 M_ALD(REG_PV, REG_PV, disp);
3995 M_JSR(REG_RA, REG_PV);
3996 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3997 M_LDA(REG_PV, REG_RA, -disp);
3999 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4001 if (m->isleafmethod)
4002 M_ALD(REG_RA, REG_SP, 1 * 8);
4004 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4005 M_LDA(REG_SP, REG_SP, 2 * 8);
4007 disp = dseg_addaddress(cd, asm_handle_exception);
4008 M_ALD(REG_ITMP3, REG_PV, disp);
4009 M_JMP(REG_ZERO, REG_ITMP3);
4013 /* generate exception check stubs */
4017 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4018 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4019 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4021 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4025 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4027 (u1 *) mcodeptr - cd->mcodebase);
4031 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4033 if (xcodeptr != NULL) {
4034 disp = xcodeptr - mcodeptr - 1;
4038 xcodeptr = mcodeptr;
4040 M_MOV(REG_PV, rd->argintregs[0]);
4041 M_MOV(REG_SP, rd->argintregs[1]);
4042 M_ALD(rd->argintregs[2],
4043 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4044 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4046 M_LDA(REG_SP, REG_SP, -1 * 8);
4047 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4049 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4050 M_ALD(REG_PV, REG_PV, disp);
4051 M_JSR(REG_RA, REG_PV);
4052 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4053 M_LDA(REG_PV, REG_RA, -disp);
4055 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4057 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4058 M_LDA(REG_SP, REG_SP, 1 * 8);
4060 disp = dseg_addaddress(cd, asm_handle_exception);
4061 M_ALD(REG_ITMP3, REG_PV, disp);
4062 M_JMP(REG_ZERO, REG_ITMP3);
4066 /* generate patcher stub call code */
4073 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4074 /* check code segment size */
4078 /* Get machine code which is patched back in later. The call is */
4079 /* 1 instruction word long. */
4081 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4084 /* patch in the call to call the following code (done at compile */
4087 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4088 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4090 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4092 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4094 /* create stack frame */
4096 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4098 /* move return address onto stack */
4100 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4102 /* move pointer to java_objectheader onto stack */
4104 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4105 /* create a virtual java_objectheader */
4107 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4108 disp = dseg_addaddress(cd, NULL); /* vftbl */
4110 M_LDA(REG_ITMP3, REG_PV, disp);
4111 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4113 M_AST(REG_ZERO, REG_SP, 4 * 8);
4116 /* move machine code onto stack */
4118 disp = dseg_adds4(cd, mcode);
4119 M_ILD(REG_ITMP3, REG_PV, disp);
4120 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4122 /* move class/method/field reference onto stack */
4124 disp = dseg_addaddress(cd, pref->ref);
4125 M_ALD(REG_ITMP3, REG_PV, disp);
4126 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4128 /* move data segment displacement onto stack */
4130 disp = dseg_adds4(cd, pref->disp);
4131 M_ILD(REG_ITMP3, REG_PV, disp);
4132 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4134 /* move patcher function pointer onto stack */
4136 disp = dseg_addaddress(cd, pref->patcher);
4137 M_ALD(REG_ITMP3, REG_PV, disp);
4138 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4140 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4141 M_ALD(REG_ITMP3, REG_PV, disp);
4142 M_JMP(REG_ZERO, REG_ITMP3);
4147 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4151 /* createcompilerstub **********************************************************
4153 Creates a stub routine which calls the compiler.
4155 *******************************************************************************/
4157 #define COMPSTUBSIZE 3
4159 functionptr createcompilerstub(methodinfo *m)
4161 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4162 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4164 /* code for the stub */
4165 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4166 M_JMP(0, REG_PV); /* jump to the compiler, return address
4167 in reg 0 is used as method pointer */
4168 s[1] = (ptrint) m; /* literals to be adressed */
4169 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4171 #if defined(STATISTICS)
4173 count_cstub_len += COMPSTUBSIZE * 8;
4176 return (functionptr) s;
4180 /* createnativestub ************************************************************
4182 Creates a stub routine which calls a native method.
4184 *******************************************************************************/
4186 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4187 registerdata *rd, methoddesc *nmd)
4189 s4 *mcodeptr; /* code generation pointer */
4190 s4 stackframesize; /* size of stackframe if needed */
4193 s4 i, j; /* count variables */
4196 s4 funcdisp; /* displacement of the function */
4198 /* initialize variables */
4201 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4204 /* calculate stack frame size */
4207 1 + /* return address */
4208 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4209 1 + /* methodinfo for call trace */
4210 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4214 /* create method header */
4216 (void) dseg_addaddress(cd, m); /* MethodPointer */
4217 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4218 (void) dseg_adds4(cd, 0); /* IsSync */
4219 (void) dseg_adds4(cd, 0); /* IsLeaf */
4220 (void) dseg_adds4(cd, 0); /* IntSave */
4221 (void) dseg_adds4(cd, 0); /* FltSave */
4222 (void) dseg_addlinenumbertablesize(cd);
4223 (void) dseg_adds4(cd, 0); /* ExTableSize */
4226 /* initialize mcode variables */
4228 mcodeptr = (s4 *) cd->mcodebase;
4229 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4232 /* generate stub code */
4234 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4235 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4238 /* call trace function */
4241 /* save integer argument registers */
4243 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4244 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4245 M_LST(rd->argintregs[i], REG_SP, j * 8);
4250 /* save and copy float arguments into integer registers */
4252 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4253 t = md->paramtypes[i].type;
4255 if (IS_FLT_DBL_TYPE(t)) {
4256 if (IS_2_WORD_TYPE(t)) {
4257 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4258 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4260 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4261 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4267 disp = dseg_addaddress(cd, m);
4268 M_ALD(REG_ITMP1, REG_PV, disp);
4269 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4270 disp = dseg_addaddress(cd, builtin_trace_args);
4271 M_ALD(REG_PV, REG_PV, disp);
4272 M_JSR(REG_RA, REG_PV);
4273 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4274 M_LDA(REG_PV, REG_RA, -disp);
4276 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4277 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4278 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4283 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4284 t = md->paramtypes[i].type;
4286 if (IS_FLT_DBL_TYPE(t)) {
4287 if (IS_2_WORD_TYPE(t)) {
4288 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4290 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4297 /* get function address (this must happen before the stackframeinfo) */
4299 funcdisp = dseg_addaddress(cd, f);
4301 #if !defined(ENABLE_STATICVM)
4303 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4305 if (opt_showdisassemble)
4311 /* save integer and float argument registers */
4313 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4314 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4315 M_LST(rd->argintregs[i], REG_SP, j * 8);
4320 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4321 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4322 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4327 /* create native stackframe info */
4330 stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo),
4332 M_MOV(REG_PV, rd->argintregs[1]);
4333 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4334 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4335 disp = dseg_addaddress(cd, stacktrace_create_native_stackframeinfo);
4336 M_ALD(REG_PV, REG_PV, disp);
4337 M_JSR(REG_RA, REG_PV);
4338 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4339 M_LDA(REG_PV, REG_RA, -disp);
4341 /* restore integer and float argument registers */
4343 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4344 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4345 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4350 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4351 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4352 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4358 /* copy or spill arguments to new locations */
4360 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4361 t = md->paramtypes[i].type;
4363 if (IS_INT_LNG_TYPE(t)) {
4364 if (!md->params[i].inmemory) {
4365 s1 = rd->argintregs[md->params[i].regoff];
4367 if (!nmd->params[j].inmemory) {
4368 s2 = rd->argintregs[nmd->params[j].regoff];
4372 s2 = nmd->params[j].regoff;
4373 M_LST(s1, REG_SP, s2 * 8);
4377 s1 = md->params[i].regoff + stackframesize;
4378 s2 = nmd->params[j].regoff;
4379 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4380 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4384 if (!md->params[i].inmemory) {
4385 s1 = rd->argfltregs[md->params[i].regoff];
4387 if (!nmd->params[j].inmemory) {
4388 s2 = rd->argfltregs[nmd->params[j].regoff];
4392 s2 = nmd->params[j].regoff;
4393 if (IS_2_WORD_TYPE(t))
4394 M_DST(s1, REG_SP, s2 * 8);
4396 M_FST(s1, REG_SP, s2 * 8);
4400 s1 = md->params[i].regoff + stackframesize;
4401 s2 = nmd->params[j].regoff;
4402 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4403 if (IS_2_WORD_TYPE(t))
4404 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4406 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4411 /* put class into second argument register */
4413 if (m->flags & ACC_STATIC) {
4414 disp = dseg_addaddress(cd, m->class);
4415 M_ALD(rd->argintregs[1], REG_PV, disp);
4418 /* put env into first argument register */
4420 disp = dseg_addaddress(cd, &env);
4421 M_ALD(rd->argintregs[0], REG_PV, disp);
4423 /* do the native function call */
4425 M_ALD(REG_PV, REG_PV, funcdisp);
4426 M_JSR(REG_RA, REG_PV); /* call native method */
4427 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4428 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4430 /* save return value */
4432 if (IS_INT_LNG_TYPE(md->returntype.type))
4433 M_LST(REG_RESULT, REG_SP, 0 * 8);
4435 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4437 /* remove native stackframe info */
4440 stackframesize * 8 - SIZEOF_VOID_P - sizeof(stackframeinfo),
4442 disp = dseg_addaddress(cd, stacktrace_remove_stackframeinfo);
4443 M_ALD(REG_PV, REG_PV, disp);
4444 M_JSR(REG_RA, REG_PV);
4445 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4446 M_LDA(REG_PV, REG_RA, -disp);
4448 /* call finished trace */
4451 disp = dseg_addaddress(cd, m);
4452 M_ALD(rd->argintregs[0], REG_PV, disp);
4454 M_MOV(REG_RESULT, rd->argintregs[1]);
4455 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4456 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4458 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4459 M_ALD(REG_PV, REG_PV, disp);
4460 M_JSR(REG_RA, REG_PV);
4461 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4462 M_LDA(REG_PV, REG_RA, -disp);
4465 /* check for exception */
4467 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4468 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4469 M_ALD(REG_PV, REG_PV, disp);
4470 M_JSR(REG_RA, REG_PV);
4471 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4472 M_LDA(REG_PV, REG_RA, -disp);
4473 M_MOV(REG_RESULT, REG_ITMP3);
4475 disp = dseg_addaddress(cd, &_exceptionptr);
4476 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4478 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4480 /* restore return value */
4482 if (IS_INT_LNG_TYPE(md->returntype.type))
4483 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4485 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4487 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4489 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4490 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4491 M_RET(REG_ZERO, REG_RA); /* return to caller */
4493 /* handle exception */
4495 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4497 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4498 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4500 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4502 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4503 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4504 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4507 /* process patcher calls **************************************************/
4515 /* there can only be one <clinit> ref entry */
4516 pref = cd->patchrefs;
4518 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4519 /* Get machine code which is patched back in later. The call is */
4520 /* 1 instruction word long. */
4522 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4523 mcode = (u4) *xcodeptr;
4525 /* patch in the call to call the following code (done at compile */
4528 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4529 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4531 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4533 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4535 /* create stack frame */
4537 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4539 /* move return address onto stack */
4541 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4543 /* move pointer to java_objectheader onto stack */
4545 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4546 /* create a virtual java_objectheader */
4548 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4549 disp = dseg_addaddress(cd, NULL); /* vftbl */
4551 M_LDA(REG_ITMP3, REG_PV, disp);
4552 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4554 M_AST(REG_ZERO, REG_SP, 4 * 8);
4557 /* move machine code onto stack */
4559 disp = dseg_adds4(cd, mcode);
4560 M_ILD(REG_ITMP3, REG_PV, disp);
4561 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4563 /* move class/method/field reference onto stack */
4565 disp = dseg_addaddress(cd, pref->ref);
4566 M_ALD(REG_ITMP3, REG_PV, disp);
4567 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4569 /* move data segment displacement onto stack */
4571 disp = dseg_adds4(cd, pref->disp);
4572 M_ILD(REG_ITMP3, REG_PV, disp);
4573 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4575 /* move patcher function pointer onto stack */
4577 disp = dseg_addaddress(cd, pref->patcher);
4578 M_ALD(REG_ITMP3, REG_PV, disp);
4579 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4581 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4582 M_ALD(REG_ITMP3, REG_PV, disp);
4583 M_JMP(REG_ZERO, REG_ITMP3);
4587 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4589 return m->entrypoint;
4594 * These are local overrides for various environment variables in Emacs.
4595 * Please do not remove this and leave it at the end of the file, where
4596 * Emacs will automagically detect them.
4597 * ---------------------------------------------------------------------
4600 * indent-tabs-mode: t