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 2992 2005-07-11 21:52:07Z twisti $
47 #include "vm/jit/alpha/arch.h"
48 #include "vm/jit/alpha/codegen.h"
49 #include "vm/jit/alpha/types.h"
50 #include "vm/jit/alpha/asmoffsets.h"
52 #include "cacao/cacao.h"
53 #include "native/native.h"
54 #include "vm/builtin.h"
55 #include "vm/global.h"
56 #include "vm/loader.h"
57 #include "vm/stringlocal.h"
58 #include "vm/tables.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/codegen.inc"
61 #include "vm/jit/jit.h"
64 # include "vm/jit/lsra.h"
65 # include "vm/jit/lsra.inc"
68 #include "vm/jit/parse.h"
69 #include "vm/jit/patcher.h"
70 #include "vm/jit/reg.h"
71 #include "vm/jit/reg.inc"
74 /* codegen *********************************************************************
76 Generates machine code.
78 *******************************************************************************/
80 void codegen(methodinfo *m, codegendata *cd, registerdata *rd)
82 s4 len, s1, s2, s3, d, disp;
92 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
93 builtintable_entry *bte;
100 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
102 /* space to save used callee saved registers */
104 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
105 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
107 parentargs_base = rd->memuse + savedregs_num;
109 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
111 if (checksync && (m->flags & ACC_SYNCHRONIZED))
116 /* create method header */
118 (void) dseg_addaddress(cd, m); /* MethodPointer */
119 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
121 #if defined(USE_THREADS)
123 /* IsSync contains the offset relative to the stack pointer for the
124 argument of monitor_exit used in the exception handler. Since the
125 offset could be zero and give a wrong meaning of the flag it is
129 if (checksync && (m->flags & ACC_SYNCHRONIZED))
130 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
135 (void) dseg_adds4(cd, 0); /* IsSync */
137 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
138 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse);/* IntSave */
139 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse);/* FltSave */
141 dseg_addlinenumbertablesize(cd);
143 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
145 /* create exception table */
147 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
148 dseg_addtarget(cd, ex->start);
149 dseg_addtarget(cd, ex->end);
150 dseg_addtarget(cd, ex->handler);
151 (void) dseg_addaddress(cd, ex->catchtype.cls);
154 /* initialize mcode variables */
156 mcodeptr = (s4 *) cd->mcodebase;
157 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
158 MCODECHECK(128 + m->paramcount);
160 /* create stack frame (if necessary) */
162 if (parentargs_base) {
163 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
166 /* save return address and used callee saved registers */
169 if (!m->isleafmethod) {
170 p--; M_AST(REG_RA, REG_SP, p * 8);
172 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
173 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
175 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
176 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
179 /* take arguments out of register or stack frame */
183 for (p = 0, l = 0; p < md->paramcount; p++) {
184 t = md->paramtypes[p].type;
185 var = &(rd->locals[l][t]);
187 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
191 s1 = md->params[p].regoff;
192 if (IS_INT_LNG_TYPE(t)) { /* integer args */
193 if (!md->params[p].inmemory) { /* register arguments */
194 s2 = rd->argintregs[s1];
195 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
196 M_INTMOVE(s2, var->regoff);
198 } else { /* reg arg -> spilled */
199 M_LST(s2, REG_SP, var->regoff * 8);
202 } else { /* stack arguments */
203 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
204 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
206 } else { /* stack arg -> spilled */
207 var->regoff = parentargs_base + s1;
211 } else { /* floating args */
212 if (!md->params[p].inmemory) { /* register arguments */
213 s2 = rd->argfltregs[s1];
214 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
215 M_FLTMOVE(s2, var->regoff);
217 } else { /* reg arg -> spilled */
218 M_DST(s2, REG_SP, var->regoff * 8);
221 } else { /* stack arguments */
222 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
223 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
225 } else { /* stack-arg -> spilled */
226 var->regoff = parentargs_base + s1;
232 /* call monitorenter function */
234 #if defined(USE_THREADS)
235 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
236 /* stack offset for monitor argument */
241 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
243 for (p = 0; p < INT_ARG_CNT; p++)
244 M_LST(rd->argintregs[p], REG_SP, p * 8);
246 for (p = 0; p < FLT_ARG_CNT; p++)
247 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
249 s1 += INT_ARG_CNT + FLT_ARG_CNT;
252 /* decide which monitor enter function to call */
254 if (m->flags & ACC_STATIC) {
255 p = dseg_addaddress(cd, m->class);
256 M_ALD(REG_ITMP1, REG_PV, p);
257 M_AST(REG_ITMP1, REG_SP, s1 * 8);
258 M_INTMOVE(REG_ITMP1, rd->argintregs[0]);
259 p = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
260 M_ALD(REG_PV, REG_PV, p);
261 M_JSR(REG_RA, REG_PV);
262 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
263 M_LDA(REG_PV, REG_RA, d);
266 M_BEQZ(rd->argintregs[0], 0);
267 codegen_addxnullrefs(cd, mcodeptr);
268 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
269 p = dseg_addaddress(cd, BUILTIN_monitorenter);
270 M_ALD(REG_PV, REG_PV, p);
271 M_JSR(REG_RA, REG_PV);
272 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
273 M_LDA(REG_PV, REG_RA, d);
277 for (p = 0; p < INT_ARG_CNT; p++)
278 M_LLD(rd->argintregs[p], REG_SP, p * 8);
280 for (p = 0; p < FLT_ARG_CNT; p++)
281 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
283 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
288 /* call trace function */
291 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
292 M_AST(REG_RA, REG_SP, 1 * 8);
294 /* save integer argument registers */
296 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
297 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
299 /* save and copy float arguments into integer registers */
301 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
302 t = md->paramtypes[p].type;
304 if (IS_FLT_DBL_TYPE(t)) {
305 if (IS_2_WORD_TYPE(t)) {
306 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
309 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
312 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
315 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
319 p = dseg_addaddress(cd, m);
320 M_ALD(REG_ITMP1, REG_PV, p);
321 M_AST(REG_ITMP1, REG_SP, 0 * 8);
322 p = dseg_addaddress(cd, (void *) builtin_trace_args);
323 M_ALD(REG_PV, REG_PV, p);
324 M_JSR(REG_RA, REG_PV);
325 d = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
326 M_LDA(REG_PV, REG_RA, d);
327 M_ALD(REG_RA, REG_SP, 1 * 8);
329 /* restore integer argument registers */
331 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
332 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
334 /* restore float argument registers */
336 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
337 t = md->paramtypes[p].type;
339 if (IS_FLT_DBL_TYPE(t)) {
340 if (IS_2_WORD_TYPE(t)) {
341 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
344 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
348 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
352 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
357 /* end of header generation */
359 /* walk through all basic blocks */
361 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
363 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
365 if (bptr->flags >= BBREACHED) {
367 /* branch resolving */
371 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
372 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
373 brefs->branchpos, bptr->mpc);
377 /* copy interface registers to their destination */
384 while (src != NULL) {
386 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
387 /* d = reg_of_var(m, src, REG_ITMP1); */
388 if (!(src->flags & INMEMORY))
392 M_INTMOVE(REG_ITMP1, d);
393 store_reg_to_var_int(src, d);
399 while (src != NULL) {
401 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
402 d = reg_of_var(rd, src, REG_ITMP1);
403 M_INTMOVE(REG_ITMP1, d);
404 store_reg_to_var_int(src, d);
407 d = reg_of_var(rd, src, REG_IFTMP);
408 if ((src->varkind != STACKVAR)) {
410 if (IS_FLT_DBL_TYPE(s2)) {
411 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
412 s1 = rd->interfaces[len][s2].regoff;
416 M_DLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
418 store_reg_to_var_flt(src, d);
421 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
422 s1 = rd->interfaces[len][s2].regoff;
426 M_LLD(d, REG_SP, 8 * rd->interfaces[len][s2].regoff);
428 store_reg_to_var_int(src, d);
438 /* walk through all instructions */
443 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
444 if (iptr->line != currentline) {
445 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
446 currentline = iptr->line;
449 MCODECHECK(64); /* an instruction usually needs < 64 words */
452 case ICMD_INLINE_START:
453 case ICMD_INLINE_END:
456 case ICMD_NOP: /* ... ==> ... */
459 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
461 var_to_reg_int(s1, src, REG_ITMP1);
463 codegen_addxnullrefs(cd, mcodeptr);
466 /* constant operations ************************************************/
468 case ICMD_ICONST: /* ... ==> ..., constant */
469 /* op1 = 0, val.i = constant */
471 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
472 ICONST(d, iptr->val.i);
473 store_reg_to_var_int(iptr->dst, d);
476 case ICMD_LCONST: /* ... ==> ..., constant */
477 /* op1 = 0, val.l = constant */
479 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
480 LCONST(d, iptr->val.l);
481 store_reg_to_var_int(iptr->dst, d);
484 case ICMD_FCONST: /* ... ==> ..., constant */
485 /* op1 = 0, val.f = constant */
487 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
488 a = dseg_addfloat(cd, iptr->val.f);
490 store_reg_to_var_flt(iptr->dst, d);
493 case ICMD_DCONST: /* ... ==> ..., constant */
494 /* op1 = 0, val.d = constant */
496 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
497 a = dseg_adddouble(cd, iptr->val.d);
499 store_reg_to_var_flt(iptr->dst, d);
502 case ICMD_ACONST: /* ... ==> ..., constant */
503 /* op1 = 0, val.a = constant */
505 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
507 a = dseg_addaddress(cd, iptr->val.a);
510 M_INTMOVE(REG_ZERO, d);
512 store_reg_to_var_int(iptr->dst, d);
516 /* load/store operations **********************************************/
518 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
519 case ICMD_LLOAD: /* op1 = local variable */
522 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
523 if ((iptr->dst->varkind == LOCALVAR) &&
524 (iptr->dst->varnum == iptr->op1))
526 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
527 if (var->flags & INMEMORY)
528 M_LLD(d, REG_SP, 8 * var->regoff);
530 {M_INTMOVE(var->regoff,d);}
531 store_reg_to_var_int(iptr->dst, d);
534 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
535 case ICMD_DLOAD: /* op1 = local variable */
537 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
538 if ((iptr->dst->varkind == LOCALVAR) &&
539 (iptr->dst->varnum == iptr->op1))
541 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
542 if (var->flags & INMEMORY)
543 M_DLD(d, REG_SP, 8 * var->regoff);
545 {M_FLTMOVE(var->regoff,d);}
546 store_reg_to_var_flt(iptr->dst, d);
550 case ICMD_ISTORE: /* ..., value ==> ... */
551 case ICMD_LSTORE: /* op1 = local variable */
554 if ((src->varkind == LOCALVAR) &&
555 (src->varnum == iptr->op1))
557 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
558 if (var->flags & INMEMORY) {
559 var_to_reg_int(s1, src, REG_ITMP1);
560 M_LST(s1, REG_SP, 8 * var->regoff);
563 var_to_reg_int(s1, src, var->regoff);
564 M_INTMOVE(s1, var->regoff);
568 case ICMD_FSTORE: /* ..., value ==> ... */
569 case ICMD_DSTORE: /* op1 = local variable */
571 if ((src->varkind == LOCALVAR) &&
572 (src->varnum == iptr->op1))
574 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
575 if (var->flags & INMEMORY) {
576 var_to_reg_flt(s1, src, REG_FTMP1);
577 M_DST(s1, REG_SP, 8 * var->regoff);
580 var_to_reg_flt(s1, src, var->regoff);
581 M_FLTMOVE(s1, var->regoff);
586 /* pop/dup/swap operations ********************************************/
588 /* attention: double and longs are only one entry in CACAO ICMDs */
590 case ICMD_POP: /* ..., value ==> ... */
591 case ICMD_POP2: /* ..., value, value ==> ... */
594 case ICMD_DUP: /* ..., a ==> ..., a, a */
595 M_COPY(src, iptr->dst);
598 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
600 M_COPY(src, iptr->dst);
601 M_COPY(src->prev, iptr->dst->prev);
602 M_COPY(iptr->dst, iptr->dst->prev->prev);
605 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
607 M_COPY(src, iptr->dst);
608 M_COPY(src->prev, iptr->dst->prev);
609 M_COPY(src->prev->prev, iptr->dst->prev->prev);
610 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
613 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
615 M_COPY(src, iptr->dst);
616 M_COPY(src->prev, iptr->dst->prev);
619 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
621 M_COPY(src, iptr->dst);
622 M_COPY(src->prev, iptr->dst->prev);
623 M_COPY(src->prev->prev, iptr->dst->prev->prev);
624 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
625 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
628 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
630 M_COPY(src, iptr->dst);
631 M_COPY(src->prev, iptr->dst->prev);
632 M_COPY(src->prev->prev, iptr->dst->prev->prev);
633 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
634 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
635 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
638 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
640 M_COPY(src, iptr->dst->prev);
641 M_COPY(src->prev, iptr->dst);
645 /* integer operations *************************************************/
647 case ICMD_INEG: /* ..., value ==> ..., - value */
649 var_to_reg_int(s1, src, REG_ITMP1);
650 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
651 M_ISUB(REG_ZERO, s1, d);
652 store_reg_to_var_int(iptr->dst, d);
655 case ICMD_LNEG: /* ..., value ==> ..., - value */
657 var_to_reg_int(s1, src, REG_ITMP1);
658 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
659 M_LSUB(REG_ZERO, s1, d);
660 store_reg_to_var_int(iptr->dst, d);
663 case ICMD_I2L: /* ..., value ==> ..., value */
665 var_to_reg_int(s1, src, REG_ITMP1);
666 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
668 store_reg_to_var_int(iptr->dst, d);
671 case ICMD_L2I: /* ..., value ==> ..., value */
673 var_to_reg_int(s1, src, REG_ITMP1);
674 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
675 M_IADD(s1, REG_ZERO, d );
676 store_reg_to_var_int(iptr->dst, d);
679 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
681 var_to_reg_int(s1, src, REG_ITMP1);
682 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
683 if (has_ext_instr_set) {
687 M_SLL_IMM(s1, 56, d);
688 M_SRA_IMM( d, 56, d);
690 store_reg_to_var_int(iptr->dst, d);
693 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
695 var_to_reg_int(s1, src, REG_ITMP1);
696 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
698 store_reg_to_var_int(iptr->dst, d);
701 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
703 var_to_reg_int(s1, src, REG_ITMP1);
704 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
705 if (has_ext_instr_set) {
709 M_SLL_IMM(s1, 48, d);
710 M_SRA_IMM( d, 48, d);
712 store_reg_to_var_int(iptr->dst, d);
716 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
718 var_to_reg_int(s1, src->prev, REG_ITMP1);
719 var_to_reg_int(s2, src, REG_ITMP2);
720 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
722 store_reg_to_var_int(iptr->dst, d);
725 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
726 /* val.i = constant */
728 var_to_reg_int(s1, src, REG_ITMP1);
729 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
730 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
731 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_ITMP3);
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_ITMP3);
754 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
755 M_LADD_IMM(s1, iptr->val.l, d);
758 LCONST(REG_ITMP2, iptr->val.l);
759 M_LADD(s1, REG_ITMP2, d);
761 store_reg_to_var_int(iptr->dst, d);
764 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
766 var_to_reg_int(s1, src->prev, REG_ITMP1);
767 var_to_reg_int(s2, src, REG_ITMP2);
768 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
770 store_reg_to_var_int(iptr->dst, d);
773 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
774 /* val.i = constant */
776 var_to_reg_int(s1, src, REG_ITMP1);
777 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
778 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
779 M_ISUB_IMM(s1, iptr->val.i, d);
782 ICONST(REG_ITMP2, iptr->val.i);
783 M_ISUB(s1, REG_ITMP2, d);
785 store_reg_to_var_int(iptr->dst, d);
788 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
790 var_to_reg_int(s1, src->prev, REG_ITMP1);
791 var_to_reg_int(s2, src, REG_ITMP2);
792 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
794 store_reg_to_var_int(iptr->dst, d);
797 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
798 /* val.l = constant */
800 var_to_reg_int(s1, src, REG_ITMP1);
801 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
802 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
803 M_LSUB_IMM(s1, iptr->val.l, d);
806 LCONST(REG_ITMP2, iptr->val.l);
807 M_LSUB(s1, REG_ITMP2, d);
809 store_reg_to_var_int(iptr->dst, d);
812 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
814 var_to_reg_int(s1, src->prev, REG_ITMP1);
815 var_to_reg_int(s2, src, REG_ITMP2);
816 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
818 store_reg_to_var_int(iptr->dst, d);
821 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
822 /* val.i = constant */
824 var_to_reg_int(s1, src, REG_ITMP1);
825 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
826 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
827 M_IMUL_IMM(s1, iptr->val.i, d);
830 ICONST(REG_ITMP2, iptr->val.i);
831 M_IMUL(s1, REG_ITMP2, d);
833 store_reg_to_var_int(iptr->dst, d);
836 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
838 var_to_reg_int(s1, src->prev, REG_ITMP1);
839 var_to_reg_int(s2, src, REG_ITMP2);
840 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
842 store_reg_to_var_int(iptr->dst, d);
845 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
846 /* val.l = constant */
848 var_to_reg_int(s1, src, REG_ITMP1);
849 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
850 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
851 M_LMUL_IMM(s1, iptr->val.l, d);
854 LCONST(REG_ITMP2, iptr->val.l);
855 M_LMUL(s1, REG_ITMP2, d);
857 store_reg_to_var_int(iptr->dst, d);
860 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
861 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
862 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
863 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
865 var_to_reg_int(s1, src->prev, REG_ITMP1);
866 var_to_reg_int(s2, src, REG_ITMP2);
867 d = reg_of_var(rd, iptr->dst, REG_RESULT);
869 codegen_addxdivrefs(cd, mcodeptr);
871 M_MOV(s1, rd->argintregs[0]);
872 M_MOV(s2, rd->argintregs[1]);
874 disp = dseg_addaddress(cd, bte->fp);
875 M_ALD(REG_PV, REG_PV, disp);
876 M_JSR(REG_RA, REG_PV);
878 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
880 M_LDA(REG_PV, REG_RA, -disp);
882 s4 ml = -disp, mh = 0;
883 while (ml < -32768) { ml += 65536; mh--; }
884 M_LDA(REG_PV, REG_RA, ml);
885 M_LDAH(REG_PV, REG_PV, mh);
888 M_INTMOVE(REG_RESULT, d);
889 store_reg_to_var_int(iptr->dst, d);
892 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
893 case ICMD_LDIVPOW2: /* val.i = constant */
895 var_to_reg_int(s1, src, REG_ITMP1);
896 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
897 if (iptr->val.i <= 15) {
898 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
899 M_CMOVGE(s1, s1, REG_ITMP2);
902 M_SRA_IMM(s1, 63, REG_ITMP2);
903 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
904 M_LADD(s1, REG_ITMP2, REG_ITMP2);
906 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
907 store_reg_to_var_int(iptr->dst, d);
910 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
912 var_to_reg_int(s1, src->prev, REG_ITMP1);
913 var_to_reg_int(s2, src, REG_ITMP2);
914 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
915 M_AND_IMM(s2, 0x1f, REG_ITMP3);
916 M_SLL(s1, REG_ITMP3, d);
917 M_IADD(d, REG_ZERO, d);
918 store_reg_to_var_int(iptr->dst, d);
921 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
922 /* val.i = constant */
924 var_to_reg_int(s1, src, REG_ITMP1);
925 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
926 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
927 M_IADD(d, REG_ZERO, d);
928 store_reg_to_var_int(iptr->dst, d);
931 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
933 var_to_reg_int(s1, src->prev, REG_ITMP1);
934 var_to_reg_int(s2, src, REG_ITMP2);
935 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
936 M_AND_IMM(s2, 0x1f, REG_ITMP3);
937 M_SRA(s1, REG_ITMP3, d);
938 store_reg_to_var_int(iptr->dst, d);
941 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
942 /* val.i = constant */
944 var_to_reg_int(s1, src, REG_ITMP1);
945 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
946 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
947 store_reg_to_var_int(iptr->dst, d);
950 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
952 var_to_reg_int(s1, src->prev, REG_ITMP1);
953 var_to_reg_int(s2, src, REG_ITMP2);
954 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
955 M_AND_IMM(s2, 0x1f, REG_ITMP2);
957 M_SRL(d, REG_ITMP2, d);
958 M_IADD(d, REG_ZERO, d);
959 store_reg_to_var_int(iptr->dst, d);
962 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
963 /* val.i = constant */
965 var_to_reg_int(s1, src, REG_ITMP1);
966 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
968 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
969 M_IADD(d, REG_ZERO, d);
970 store_reg_to_var_int(iptr->dst, d);
973 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
975 var_to_reg_int(s1, src->prev, REG_ITMP1);
976 var_to_reg_int(s2, src, REG_ITMP2);
977 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
979 store_reg_to_var_int(iptr->dst, d);
982 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
983 /* val.i = constant */
985 var_to_reg_int(s1, src, REG_ITMP1);
986 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
987 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
988 store_reg_to_var_int(iptr->dst, d);
991 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
993 var_to_reg_int(s1, src->prev, REG_ITMP1);
994 var_to_reg_int(s2, src, REG_ITMP2);
995 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
997 store_reg_to_var_int(iptr->dst, d);
1000 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1001 /* val.i = constant */
1003 var_to_reg_int(s1, src, REG_ITMP1);
1004 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1005 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1006 store_reg_to_var_int(iptr->dst, d);
1009 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1011 var_to_reg_int(s1, src->prev, REG_ITMP1);
1012 var_to_reg_int(s2, src, REG_ITMP2);
1013 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1015 store_reg_to_var_int(iptr->dst, d);
1018 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1019 /* val.i = constant */
1021 var_to_reg_int(s1, src, REG_ITMP1);
1022 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1023 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1024 store_reg_to_var_int(iptr->dst, d);
1027 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1030 var_to_reg_int(s1, src->prev, REG_ITMP1);
1031 var_to_reg_int(s2, src, REG_ITMP2);
1032 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1034 store_reg_to_var_int(iptr->dst, d);
1037 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1038 /* val.i = constant */
1040 var_to_reg_int(s1, src, REG_ITMP1);
1041 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1042 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1043 M_AND_IMM(s1, iptr->val.i, d);
1045 else if (iptr->val.i == 0xffff) {
1048 else if (iptr->val.i == 0xffffff) {
1049 M_ZAPNOT_IMM(s1, 0x07, d);
1052 ICONST(REG_ITMP2, iptr->val.i);
1053 M_AND(s1, REG_ITMP2, d);
1055 store_reg_to_var_int(iptr->dst, d);
1058 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1059 /* val.i = constant */
1061 var_to_reg_int(s1, src, REG_ITMP1);
1062 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1064 M_MOV(s1, REG_ITMP1);
1067 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1068 M_AND_IMM(s1, iptr->val.i, d);
1070 M_ISUB(REG_ZERO, s1, d);
1071 M_AND_IMM(d, iptr->val.i, d);
1073 else if (iptr->val.i == 0xffff) {
1076 M_ISUB(REG_ZERO, s1, d);
1079 else if (iptr->val.i == 0xffffff) {
1080 M_ZAPNOT_IMM(s1, 0x07, d);
1082 M_ISUB(REG_ZERO, s1, d);
1083 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_ITMP3);
1101 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1102 M_AND_IMM(s1, iptr->val.l, d);
1104 else if (iptr->val.l == 0xffffL) {
1107 else if (iptr->val.l == 0xffffffL) {
1108 M_ZAPNOT_IMM(s1, 0x07, d);
1110 else if (iptr->val.l == 0xffffffffL) {
1113 else if (iptr->val.l == 0xffffffffffL) {
1114 M_ZAPNOT_IMM(s1, 0x1f, d);
1116 else if (iptr->val.l == 0xffffffffffffL) {
1117 M_ZAPNOT_IMM(s1, 0x3f, d);
1119 else if (iptr->val.l == 0xffffffffffffffL) {
1120 M_ZAPNOT_IMM(s1, 0x7f, d);
1123 LCONST(REG_ITMP2, iptr->val.l);
1124 M_AND(s1, REG_ITMP2, d);
1126 store_reg_to_var_int(iptr->dst, d);
1129 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1130 /* val.l = constant */
1132 var_to_reg_int(s1, src, REG_ITMP1);
1133 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1135 M_MOV(s1, REG_ITMP1);
1138 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1139 M_AND_IMM(s1, iptr->val.l, d);
1141 M_LSUB(REG_ZERO, s1, d);
1142 M_AND_IMM(d, iptr->val.l, d);
1144 else if (iptr->val.l == 0xffffL) {
1147 M_LSUB(REG_ZERO, s1, d);
1150 else if (iptr->val.l == 0xffffffL) {
1151 M_ZAPNOT_IMM(s1, 0x07, d);
1153 M_LSUB(REG_ZERO, s1, d);
1154 M_ZAPNOT_IMM(d, 0x07, d);
1156 else if (iptr->val.l == 0xffffffffL) {
1159 M_LSUB(REG_ZERO, s1, d);
1162 else if (iptr->val.l == 0xffffffffffL) {
1163 M_ZAPNOT_IMM(s1, 0x1f, d);
1165 M_LSUB(REG_ZERO, s1, d);
1166 M_ZAPNOT_IMM(d, 0x1f, d);
1168 else if (iptr->val.l == 0xffffffffffffL) {
1169 M_ZAPNOT_IMM(s1, 0x3f, d);
1171 M_LSUB(REG_ZERO, s1, d);
1172 M_ZAPNOT_IMM(d, 0x3f, d);
1174 else if (iptr->val.l == 0xffffffffffffffL) {
1175 M_ZAPNOT_IMM(s1, 0x7f, d);
1177 M_LSUB(REG_ZERO, s1, d);
1178 M_ZAPNOT_IMM(d, 0x7f, d);
1181 LCONST(REG_ITMP2, iptr->val.l);
1182 M_AND(s1, REG_ITMP2, d);
1184 M_LSUB(REG_ZERO, s1, d);
1185 M_AND(d, REG_ITMP2, d);
1187 M_LSUB(REG_ZERO, d, d);
1188 store_reg_to_var_int(iptr->dst, d);
1191 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1194 var_to_reg_int(s1, src->prev, REG_ITMP1);
1195 var_to_reg_int(s2, src, REG_ITMP2);
1196 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1198 store_reg_to_var_int(iptr->dst, d);
1201 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1202 /* val.i = constant */
1204 var_to_reg_int(s1, src, REG_ITMP1);
1205 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1206 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1207 M_OR_IMM(s1, iptr->val.i, d);
1210 ICONST(REG_ITMP2, iptr->val.i);
1211 M_OR(s1, REG_ITMP2, d);
1213 store_reg_to_var_int(iptr->dst, d);
1216 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1217 /* val.l = constant */
1219 var_to_reg_int(s1, src, REG_ITMP1);
1220 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1221 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1222 M_OR_IMM(s1, iptr->val.l, d);
1225 LCONST(REG_ITMP2, iptr->val.l);
1226 M_OR(s1, REG_ITMP2, d);
1228 store_reg_to_var_int(iptr->dst, d);
1231 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1234 var_to_reg_int(s1, src->prev, REG_ITMP1);
1235 var_to_reg_int(s2, src, REG_ITMP2);
1236 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1238 store_reg_to_var_int(iptr->dst, d);
1241 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1242 /* val.i = constant */
1244 var_to_reg_int(s1, src, REG_ITMP1);
1245 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1246 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1247 M_XOR_IMM(s1, iptr->val.i, d);
1250 ICONST(REG_ITMP2, iptr->val.i);
1251 M_XOR(s1, REG_ITMP2, d);
1253 store_reg_to_var_int(iptr->dst, d);
1256 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1257 /* val.l = constant */
1259 var_to_reg_int(s1, src, REG_ITMP1);
1260 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1261 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1262 M_XOR_IMM(s1, iptr->val.l, d);
1265 LCONST(REG_ITMP2, iptr->val.l);
1266 M_XOR(s1, REG_ITMP2, d);
1268 store_reg_to_var_int(iptr->dst, d);
1272 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1274 var_to_reg_int(s1, src->prev, REG_ITMP1);
1275 var_to_reg_int(s2, src, REG_ITMP2);
1276 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1277 M_CMPLT(s1, s2, REG_ITMP3);
1278 M_CMPLT(s2, s1, REG_ITMP1);
1279 M_LSUB (REG_ITMP1, REG_ITMP3, d);
1280 store_reg_to_var_int(iptr->dst, d);
1284 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1285 /* op1 = variable, val.i = constant */
1287 var = &(rd->locals[iptr->op1][TYPE_INT]);
1288 if (var->flags & INMEMORY) {
1290 M_LLD(s1, REG_SP, 8 * var->regoff);
1294 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1295 M_IADD_IMM(s1, iptr->val.i, s1);
1297 else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1298 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1301 M_LDA (s1, s1, iptr->val.i);
1302 M_IADD(s1, REG_ZERO, s1);
1304 if (var->flags & INMEMORY)
1305 M_LST(s1, REG_SP, 8 * var->regoff);
1309 /* floating operations ************************************************/
1311 case ICMD_FNEG: /* ..., value ==> ..., - value */
1313 var_to_reg_flt(s1, src, REG_FTMP1);
1314 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1316 store_reg_to_var_flt(iptr->dst, d);
1319 case ICMD_DNEG: /* ..., value ==> ..., - value */
1321 var_to_reg_flt(s1, src, REG_FTMP1);
1322 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1324 store_reg_to_var_flt(iptr->dst, d);
1327 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1329 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1330 var_to_reg_flt(s2, src, REG_FTMP2);
1331 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1336 if (d == s1 || d == s2) {
1337 M_FADDS(s1, s2, REG_FTMP3);
1339 M_FMOV(REG_FTMP3, d);
1346 store_reg_to_var_flt(iptr->dst, d);
1349 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1351 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1352 var_to_reg_flt(s2, src, REG_FTMP2);
1353 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1358 if (d == s1 || d == s2) {
1359 M_DADDS(s1, s2, REG_FTMP3);
1361 M_FMOV(REG_FTMP3, d);
1368 store_reg_to_var_flt(iptr->dst, d);
1371 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1373 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1374 var_to_reg_flt(s2, src, REG_FTMP2);
1375 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1380 if (d == s1 || d == s2) {
1381 M_FSUBS(s1, s2, REG_FTMP3);
1383 M_FMOV(REG_FTMP3, d);
1390 store_reg_to_var_flt(iptr->dst, d);
1393 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1395 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1396 var_to_reg_flt(s2, src, REG_FTMP2);
1397 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1402 if (d == s1 || d == s2) {
1403 M_DSUBS(s1, s2, REG_FTMP3);
1405 M_FMOV(REG_FTMP3, d);
1412 store_reg_to_var_flt(iptr->dst, d);
1415 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1417 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1418 var_to_reg_flt(s2, src, REG_FTMP2);
1419 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1424 if (d == s1 || d == s2) {
1425 M_FMULS(s1, s2, REG_FTMP3);
1427 M_FMOV(REG_FTMP3, d);
1434 store_reg_to_var_flt(iptr->dst, d);
1437 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1439 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1440 var_to_reg_flt(s2, src, REG_FTMP2);
1441 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1446 if (d == s1 || d == s2) {
1447 M_DMULS(s1, s2, REG_FTMP3);
1449 M_FMOV(REG_FTMP3, d);
1456 store_reg_to_var_flt(iptr->dst, d);
1459 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1461 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1462 var_to_reg_flt(s2, src, REG_FTMP2);
1463 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1468 if (d == s1 || d == s2) {
1469 M_FDIVS(s1, s2, REG_FTMP3);
1471 M_FMOV(REG_FTMP3, d);
1478 store_reg_to_var_flt(iptr->dst, d);
1481 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1483 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1484 var_to_reg_flt(s2, src, REG_FTMP2);
1485 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1490 if (d == s1 || d == s2) {
1491 M_DDIVS(s1, s2, REG_FTMP3);
1493 M_FMOV(REG_FTMP3, d);
1500 store_reg_to_var_flt(iptr->dst, d);
1503 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1505 var_to_reg_int(s1, src, REG_ITMP1);
1506 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1507 a = dseg_adddouble(cd, 0.0);
1508 M_LST (s1, REG_PV, a);
1509 M_DLD (d, REG_PV, a);
1511 store_reg_to_var_flt(iptr->dst, d);
1514 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1516 var_to_reg_int(s1, src, REG_ITMP1);
1517 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1518 a = dseg_adddouble(cd, 0.0);
1519 M_LST (s1, REG_PV, a);
1520 M_DLD (d, REG_PV, a);
1522 store_reg_to_var_flt(iptr->dst, d);
1525 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1527 var_to_reg_flt(s1, src, REG_FTMP1);
1528 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1529 a = dseg_adddouble(cd, 0.0);
1530 M_CVTDL_C(s1, REG_FTMP2);
1531 M_CVTLI(REG_FTMP2, REG_FTMP3);
1532 M_DST (REG_FTMP3, REG_PV, a);
1533 M_ILD (d, REG_PV, a);
1534 store_reg_to_var_int(iptr->dst, d);
1537 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1539 var_to_reg_flt(s1, src, REG_FTMP1);
1540 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1541 a = dseg_adddouble(cd, 0.0);
1542 M_CVTDL_C(s1, REG_FTMP2);
1543 M_DST (REG_FTMP2, REG_PV, a);
1544 M_LLD (d, REG_PV, a);
1545 store_reg_to_var_int(iptr->dst, d);
1548 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1550 var_to_reg_flt(s1, src, REG_FTMP1);
1551 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1554 store_reg_to_var_flt(iptr->dst, d);
1557 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1559 var_to_reg_flt(s1, src, REG_FTMP1);
1560 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1568 store_reg_to_var_flt(iptr->dst, d);
1571 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1573 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1574 var_to_reg_flt(s2, src, REG_FTMP2);
1575 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1577 M_LSUB_IMM(REG_ZERO, 1, d);
1578 M_FCMPEQ(s1, s2, REG_FTMP3);
1579 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1581 M_FCMPLT(s2, s1, REG_FTMP3);
1582 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1583 M_LADD_IMM(REG_ZERO, 1, d);
1586 M_LSUB_IMM(REG_ZERO, 1, d);
1587 M_FCMPEQS(s1, s2, REG_FTMP3);
1589 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1591 M_FCMPLTS(s2, s1, REG_FTMP3);
1593 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1594 M_LADD_IMM(REG_ZERO, 1, d);
1596 store_reg_to_var_int(iptr->dst, d);
1599 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1601 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1602 var_to_reg_flt(s2, src, REG_FTMP2);
1603 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1605 M_LADD_IMM(REG_ZERO, 1, d);
1606 M_FCMPEQ(s1, s2, REG_FTMP3);
1607 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1609 M_FCMPLT(s1, s2, REG_FTMP3);
1610 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1611 M_LSUB_IMM(REG_ZERO, 1, d);
1614 M_LADD_IMM(REG_ZERO, 1, d);
1615 M_FCMPEQS(s1, s2, REG_FTMP3);
1617 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1619 M_FCMPLTS(s1, s2, REG_FTMP3);
1621 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1622 M_LSUB_IMM(REG_ZERO, 1, d);
1624 store_reg_to_var_int(iptr->dst, d);
1628 /* memory operations **************************************************/
1630 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1632 var_to_reg_int(s1, src, REG_ITMP1);
1633 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1634 gen_nullptr_check(s1);
1635 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1636 store_reg_to_var_int(iptr->dst, d);
1639 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1641 var_to_reg_int(s1, src->prev, REG_ITMP1);
1642 var_to_reg_int(s2, src, REG_ITMP2);
1643 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1644 if (iptr->op1 == 0) {
1645 gen_nullptr_check(s1);
1648 M_SAADDQ(s2, s1, REG_ITMP1);
1649 M_ALD( d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1650 store_reg_to_var_int(iptr->dst, d);
1653 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1655 var_to_reg_int(s1, src->prev, REG_ITMP1);
1656 var_to_reg_int(s2, src, REG_ITMP2);
1657 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1658 if (iptr->op1 == 0) {
1659 gen_nullptr_check(s1);
1662 M_S8ADDQ(s2, s1, REG_ITMP1);
1663 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1664 store_reg_to_var_int(iptr->dst, d);
1667 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1669 var_to_reg_int(s1, src->prev, REG_ITMP1);
1670 var_to_reg_int(s2, src, REG_ITMP2);
1671 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1672 if (iptr->op1 == 0) {
1673 gen_nullptr_check(s1);
1677 M_S4ADDQ(s2, s1, REG_ITMP1);
1678 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1679 store_reg_to_var_int(iptr->dst, d);
1682 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1684 var_to_reg_int(s1, src->prev, REG_ITMP1);
1685 var_to_reg_int(s2, src, REG_ITMP2);
1686 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1687 if (iptr->op1 == 0) {
1688 gen_nullptr_check(s1);
1691 M_S4ADDQ(s2, s1, REG_ITMP1);
1692 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1693 store_reg_to_var_flt(iptr->dst, d);
1696 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1698 var_to_reg_int(s1, src->prev, REG_ITMP1);
1699 var_to_reg_int(s2, src, REG_ITMP2);
1700 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1701 if (iptr->op1 == 0) {
1702 gen_nullptr_check(s1);
1705 M_S8ADDQ(s2, s1, REG_ITMP1);
1706 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1707 store_reg_to_var_flt(iptr->dst, d);
1710 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1712 var_to_reg_int(s1, src->prev, REG_ITMP1);
1713 var_to_reg_int(s2, src, REG_ITMP2);
1714 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1715 if (iptr->op1 == 0) {
1716 gen_nullptr_check(s1);
1719 if (has_ext_instr_set) {
1720 M_LADD(s2, s1, REG_ITMP1);
1721 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1722 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1725 M_LADD (s2, s1, REG_ITMP1);
1726 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1727 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1728 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1729 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1731 store_reg_to_var_int(iptr->dst, d);
1734 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1736 var_to_reg_int(s1, src->prev, REG_ITMP1);
1737 var_to_reg_int(s2, src, REG_ITMP2);
1738 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1739 if (iptr->op1 == 0) {
1740 gen_nullptr_check(s1);
1743 if (has_ext_instr_set) {
1744 M_LADD(s2, s1, REG_ITMP1);
1745 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1746 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1750 M_LADD(s2, s1, REG_ITMP1);
1751 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1752 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1753 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1754 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1755 M_SRA_IMM(d, 48, d);
1757 store_reg_to_var_int(iptr->dst, d);
1760 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1762 var_to_reg_int(s1, src->prev, REG_ITMP1);
1763 var_to_reg_int(s2, src, REG_ITMP2);
1764 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1765 if (iptr->op1 == 0) {
1766 gen_nullptr_check(s1);
1769 if (has_ext_instr_set) {
1770 M_LADD (s2, s1, REG_ITMP1);
1771 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1775 M_LADD(s2, s1, REG_ITMP1);
1776 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1777 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1778 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1779 M_SRA_IMM(d, 56, d);
1781 store_reg_to_var_int(iptr->dst, d);
1785 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1787 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1788 var_to_reg_int(s2, src->prev, REG_ITMP2);
1789 if (iptr->op1 == 0) {
1790 gen_nullptr_check(s1);
1793 var_to_reg_int(s3, src, REG_ITMP3);
1794 M_S8ADDQ(s2, s1, REG_ITMP1);
1795 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1798 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1800 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1801 var_to_reg_int(s2, src->prev, REG_ITMP2);
1802 if (iptr->op1 == 0) {
1803 gen_nullptr_check(s1);
1806 var_to_reg_int(s3, src, REG_ITMP3);
1807 M_S4ADDQ(s2, s1, REG_ITMP1);
1808 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1811 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1813 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1814 var_to_reg_int(s2, src->prev, REG_ITMP2);
1815 if (iptr->op1 == 0) {
1816 gen_nullptr_check(s1);
1819 var_to_reg_flt(s3, src, REG_FTMP3);
1820 M_S4ADDQ(s2, s1, REG_ITMP1);
1821 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1824 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1826 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1827 var_to_reg_int(s2, src->prev, REG_ITMP2);
1828 if (iptr->op1 == 0) {
1829 gen_nullptr_check(s1);
1832 var_to_reg_flt(s3, src, REG_FTMP3);
1833 M_S8ADDQ(s2, s1, REG_ITMP1);
1834 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1837 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1839 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1840 var_to_reg_int(s2, src->prev, REG_ITMP2);
1841 if (iptr->op1 == 0) {
1842 gen_nullptr_check(s1);
1845 var_to_reg_int(s3, src, REG_ITMP3);
1846 if (has_ext_instr_set) {
1847 M_LADD(s2, s1, REG_ITMP1);
1848 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1849 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1851 M_LADD(s2, s1, REG_ITMP1);
1852 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1853 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1854 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1855 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1856 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1857 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1858 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1862 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1864 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1865 var_to_reg_int(s2, src->prev, REG_ITMP2);
1866 if (iptr->op1 == 0) {
1867 gen_nullptr_check(s1);
1870 var_to_reg_int(s3, src, REG_ITMP3);
1871 if (has_ext_instr_set) {
1872 M_LADD(s2, s1, REG_ITMP1);
1873 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1874 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1876 M_LADD(s2, s1, REG_ITMP1);
1877 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1878 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1879 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1880 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1881 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1882 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1883 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1887 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1889 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1890 var_to_reg_int(s2, src->prev, REG_ITMP2);
1891 if (iptr->op1 == 0) {
1892 gen_nullptr_check(s1);
1895 var_to_reg_int(s3, src, REG_ITMP3);
1896 if (has_ext_instr_set) {
1897 M_LADD(s2, s1, REG_ITMP1);
1898 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1900 M_LADD(s2, s1, REG_ITMP1);
1901 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1902 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1903 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1904 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1905 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1906 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1910 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1912 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1913 var_to_reg_int(s2, src->prev, REG_ITMP2);
1914 /* if (iptr->op1 == 0) { */
1915 gen_nullptr_check(s1);
1918 var_to_reg_int(s3, src, REG_ITMP3);
1920 M_MOV(s1, rd->argintregs[0]);
1921 M_MOV(s3, rd->argintregs[1]);
1923 disp = dseg_addaddress(cd, bte->fp);
1924 M_ALD(REG_PV, REG_PV, disp);
1925 M_JSR(REG_RA, REG_PV);
1927 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1929 M_LDA(REG_PV, REG_RA, -disp);
1931 s4 ml = -disp, mh = 0;
1932 while (ml < -32768) { ml += 65536; mh--; }
1933 M_LDA(REG_PV, REG_RA, ml);
1934 M_LDAH(REG_PV, REG_PV, mh);
1937 M_BEQZ(REG_RESULT, 0);
1938 codegen_addxstorerefs(cd, mcodeptr);
1940 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1941 var_to_reg_int(s2, src->prev, REG_ITMP2);
1942 var_to_reg_int(s3, src, REG_ITMP3);
1943 M_SAADDQ(s2, s1, REG_ITMP1);
1944 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1948 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1950 var_to_reg_int(s1, src->prev, REG_ITMP1);
1951 var_to_reg_int(s2, src, REG_ITMP2);
1952 if (iptr->op1 == 0) {
1953 gen_nullptr_check(s1);
1956 M_S4ADDQ(s2, s1, REG_ITMP1);
1957 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1960 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1962 var_to_reg_int(s1, src->prev, REG_ITMP1);
1963 var_to_reg_int(s2, src, REG_ITMP2);
1964 if (iptr->op1 == 0) {
1965 gen_nullptr_check(s1);
1968 M_S8ADDQ(s2, s1, REG_ITMP1);
1969 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1972 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1974 var_to_reg_int(s1, src->prev, REG_ITMP1);
1975 var_to_reg_int(s2, src, REG_ITMP2);
1976 if (iptr->op1 == 0) {
1977 gen_nullptr_check(s1);
1980 M_SAADDQ(s2, s1, REG_ITMP1);
1981 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1984 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1986 var_to_reg_int(s1, src->prev, REG_ITMP1);
1987 var_to_reg_int(s2, src, REG_ITMP2);
1988 if (iptr->op1 == 0) {
1989 gen_nullptr_check(s1);
1992 if (has_ext_instr_set) {
1993 M_LADD(s2, s1, REG_ITMP1);
1994 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1997 M_LADD(s2, s1, REG_ITMP1);
1998 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1999 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
2000 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2001 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2002 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2003 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2007 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
2009 var_to_reg_int(s1, src->prev, REG_ITMP1);
2010 var_to_reg_int(s2, src, REG_ITMP2);
2011 if (iptr->op1 == 0) {
2012 gen_nullptr_check(s1);
2015 if (has_ext_instr_set) {
2016 M_LADD(s2, s1, REG_ITMP1);
2017 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2018 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
2021 M_LADD(s2, s1, REG_ITMP1);
2022 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2023 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
2024 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
2025 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2026 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2027 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2028 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2032 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
2034 var_to_reg_int(s1, src->prev, REG_ITMP1);
2035 var_to_reg_int(s2, src, REG_ITMP2);
2036 if (iptr->op1 == 0) {
2037 gen_nullptr_check(s1);
2040 if (has_ext_instr_set) {
2041 M_LADD(s2, s1, REG_ITMP1);
2042 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2043 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2046 M_LADD(s2, s1, REG_ITMP1);
2047 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2048 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2049 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2050 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2051 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2052 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2053 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2058 case ICMD_GETSTATIC: /* ... ==> ..., value */
2059 /* op1 = type, val.a = field address */
2062 codegen_addpatchref(cd, mcodeptr,
2063 PATCHER_get_putstatic,
2064 (unresolved_field *) iptr->target);
2066 if (opt_showdisassemble)
2072 fieldinfo *fi = iptr->val.a;
2074 if (!fi->class->initialized) {
2075 codegen_addpatchref(cd, mcodeptr,
2076 PATCHER_clinit, fi->class);
2078 if (opt_showdisassemble)
2082 a = (ptrint) &(fi->value);
2085 a = dseg_addaddress(cd, a);
2086 M_ALD(REG_ITMP1, REG_PV, a);
2087 switch (iptr->op1) {
2089 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2090 M_ILD(d, REG_ITMP1, 0);
2091 store_reg_to_var_int(iptr->dst, d);
2094 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2095 M_LLD(d, REG_ITMP1, 0);
2096 store_reg_to_var_int(iptr->dst, d);
2099 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2100 M_ALD(d, REG_ITMP1, 0);
2101 store_reg_to_var_int(iptr->dst, d);
2104 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2105 M_FLD(d, REG_ITMP1, 0);
2106 store_reg_to_var_flt(iptr->dst, d);
2109 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2110 M_DLD(d, REG_ITMP1, 0);
2111 store_reg_to_var_flt(iptr->dst, d);
2116 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2117 /* op1 = type, val.a = field address */
2120 codegen_addpatchref(cd, mcodeptr,
2121 PATCHER_get_putstatic,
2122 (unresolved_field *) iptr->target);
2124 if (opt_showdisassemble)
2130 fieldinfo *fi = iptr->val.a;
2132 if (!fi->class->initialized) {
2133 codegen_addpatchref(cd, mcodeptr,
2134 PATCHER_clinit, fi->class);
2136 if (opt_showdisassemble)
2140 a = (ptrint) &(fi->value);
2143 a = dseg_addaddress(cd, a);
2144 M_ALD(REG_ITMP1, REG_PV, a);
2145 switch (iptr->op1) {
2147 var_to_reg_int(s2, src, REG_ITMP2);
2148 M_IST(s2, REG_ITMP1, 0);
2151 var_to_reg_int(s2, src, REG_ITMP2);
2152 M_LST(s2, REG_ITMP1, 0);
2155 var_to_reg_int(s2, src, REG_ITMP2);
2156 M_AST(s2, REG_ITMP1, 0);
2159 var_to_reg_flt(s2, src, REG_FTMP2);
2160 M_FST(s2, REG_ITMP1, 0);
2163 var_to_reg_flt(s2, src, REG_FTMP2);
2164 M_DST(s2, REG_ITMP1, 0);
2169 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2170 /* val = value (in current instruction) */
2171 /* op1 = type, val.a = field address (in */
2172 /* following NOP) */
2174 if (!iptr[1].val.a) {
2175 codegen_addpatchref(cd, mcodeptr,
2176 PATCHER_get_putstatic,
2177 (unresolved_field *) iptr[1].target);
2179 if (opt_showdisassemble)
2185 fieldinfo *fi = iptr[1].val.a;
2187 if (!fi->class->initialized) {
2188 codegen_addpatchref(cd, mcodeptr,
2189 PATCHER_clinit, fi->class);
2191 if (opt_showdisassemble)
2195 a = (ptrint) &(fi->value);
2198 a = dseg_addaddress(cd, a);
2199 M_ALD(REG_ITMP1, REG_PV, a);
2200 switch (iptr->op1) {
2202 M_IST(REG_ZERO, REG_ITMP1, 0);
2205 M_LST(REG_ZERO, REG_ITMP1, 0);
2208 M_AST(REG_ZERO, REG_ITMP1, 0);
2211 M_FST(REG_ZERO, REG_ITMP1, 0);
2214 M_DST(REG_ZERO, REG_ITMP1, 0);
2220 case ICMD_GETFIELD: /* ... ==> ..., value */
2221 /* op1 = type, val.i = field offset */
2223 var_to_reg_int(s1, src, REG_ITMP1);
2224 gen_nullptr_check(s1);
2227 codegen_addpatchref(cd, mcodeptr,
2228 PATCHER_get_putfield,
2229 (unresolved_field *) iptr->target);
2231 if (opt_showdisassemble)
2237 a = ((fieldinfo *) (iptr->val.a))->offset;
2240 switch (iptr->op1) {
2242 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2244 store_reg_to_var_int(iptr->dst, d);
2247 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2249 store_reg_to_var_int(iptr->dst, d);
2252 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2254 store_reg_to_var_int(iptr->dst, d);
2257 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2259 store_reg_to_var_flt(iptr->dst, d);
2262 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
2264 store_reg_to_var_flt(iptr->dst, d);
2269 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2270 /* op1 = type, val.a = field address */
2272 var_to_reg_int(s1, src->prev, REG_ITMP1);
2273 gen_nullptr_check(s1);
2275 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2276 var_to_reg_int(s2, src, REG_ITMP2);
2278 var_to_reg_flt(s2, src, REG_FTMP2);
2282 codegen_addpatchref(cd, mcodeptr,
2283 PATCHER_get_putfield,
2284 (unresolved_field *) iptr->target);
2286 if (opt_showdisassemble)
2292 a = ((fieldinfo *) (iptr->val.a))->offset;
2295 switch (iptr->op1) {
2314 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2315 /* val = value (in current instruction) */
2316 /* op1 = type, val.a = field address (in */
2317 /* following NOP) */
2319 var_to_reg_int(s1, src, REG_ITMP1);
2320 gen_nullptr_check(s1);
2322 if (!iptr[1].val.a) {
2323 codegen_addpatchref(cd, mcodeptr,
2324 PATCHER_get_putfield,
2325 (unresolved_field *) iptr[1].target);
2327 if (opt_showdisassemble)
2333 a = ((fieldinfo *) (iptr[1].val.a))->offset;
2336 switch (iptr[1].op1) {
2338 M_IST(REG_ZERO, s1, a);
2341 M_LST(REG_ZERO, s1, a);
2344 M_AST(REG_ZERO, s1, a);
2347 M_FST(REG_ZERO, s1, a);
2350 M_DST(REG_ZERO, s1, a);
2356 /* branch operations **************************************************/
2358 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2360 var_to_reg_int(s1, src, REG_ITMP1);
2361 M_INTMOVE(s1, REG_ITMP1_XPTR);
2362 a = dseg_addaddress(cd, asm_handle_exception);
2363 M_ALD(REG_ITMP2, REG_PV, a);
2364 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2365 M_NOP; /* nop ensures that XPC is less than the end */
2366 /* of basic block */
2370 case ICMD_GOTO: /* ... ==> ... */
2371 /* op1 = target JavaVM pc */
2373 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2377 case ICMD_JSR: /* ... ==> ... */
2378 /* op1 = target JavaVM pc */
2380 M_BSR(REG_ITMP1, 0);
2381 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2384 case ICMD_RET: /* ... ==> ... */
2385 /* op1 = local variable */
2387 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2388 if (var->flags & INMEMORY) {
2389 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2390 M_RET(REG_ZERO, REG_ITMP1);
2393 M_RET(REG_ZERO, var->regoff);
2397 case ICMD_IFNULL: /* ..., value ==> ... */
2398 /* op1 = target JavaVM pc */
2400 var_to_reg_int(s1, src, REG_ITMP1);
2402 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2405 case ICMD_IFNONNULL: /* ..., value ==> ... */
2406 /* op1 = target JavaVM pc */
2408 var_to_reg_int(s1, src, REG_ITMP1);
2410 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2413 case ICMD_IFEQ: /* ..., value ==> ... */
2414 /* op1 = target JavaVM pc, val.i = constant */
2416 var_to_reg_int(s1, src, REG_ITMP1);
2417 if (iptr->val.i == 0) {
2421 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2422 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2425 ICONST(REG_ITMP2, iptr->val.i);
2426 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2428 M_BNEZ(REG_ITMP1, 0);
2430 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2433 case ICMD_IFLT: /* ..., value ==> ... */
2434 /* op1 = target JavaVM pc, val.i = constant */
2436 var_to_reg_int(s1, src, REG_ITMP1);
2437 if (iptr->val.i == 0) {
2441 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2442 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2445 ICONST(REG_ITMP2, iptr->val.i);
2446 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2448 M_BNEZ(REG_ITMP1, 0);
2450 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2453 case ICMD_IFLE: /* ..., value ==> ... */
2454 /* op1 = target JavaVM pc, val.i = constant */
2456 var_to_reg_int(s1, src, REG_ITMP1);
2457 if (iptr->val.i == 0) {
2461 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2462 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2465 ICONST(REG_ITMP2, iptr->val.i);
2466 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2468 M_BNEZ(REG_ITMP1, 0);
2470 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2473 case ICMD_IFNE: /* ..., value ==> ... */
2474 /* op1 = target JavaVM pc, val.i = constant */
2476 var_to_reg_int(s1, src, REG_ITMP1);
2477 if (iptr->val.i == 0) {
2481 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2482 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2485 ICONST(REG_ITMP2, iptr->val.i);
2486 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2488 M_BEQZ(REG_ITMP1, 0);
2490 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2493 case ICMD_IFGT: /* ..., value ==> ... */
2494 /* op1 = target JavaVM pc, val.i = constant */
2496 var_to_reg_int(s1, src, REG_ITMP1);
2497 if (iptr->val.i == 0) {
2501 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2502 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2505 ICONST(REG_ITMP2, iptr->val.i);
2506 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2508 M_BEQZ(REG_ITMP1, 0);
2510 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2513 case ICMD_IFGE: /* ..., value ==> ... */
2514 /* op1 = target JavaVM pc, val.i = constant */
2516 var_to_reg_int(s1, src, REG_ITMP1);
2517 if (iptr->val.i == 0) {
2521 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2522 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2525 ICONST(REG_ITMP2, iptr->val.i);
2526 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2528 M_BEQZ(REG_ITMP1, 0);
2530 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2533 case ICMD_IF_LEQ: /* ..., value ==> ... */
2534 /* op1 = target JavaVM pc, val.l = constant */
2536 var_to_reg_int(s1, src, REG_ITMP1);
2537 if (iptr->val.l == 0) {
2541 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2542 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2545 LCONST(REG_ITMP2, iptr->val.l);
2546 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2548 M_BNEZ(REG_ITMP1, 0);
2550 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2553 case ICMD_IF_LLT: /* ..., value ==> ... */
2554 /* op1 = target JavaVM pc, val.l = constant */
2556 var_to_reg_int(s1, src, REG_ITMP1);
2557 if (iptr->val.l == 0) {
2561 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2562 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2565 LCONST(REG_ITMP2, iptr->val.l);
2566 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2568 M_BNEZ(REG_ITMP1, 0);
2570 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2573 case ICMD_IF_LLE: /* ..., value ==> ... */
2574 /* op1 = target JavaVM pc, val.l = constant */
2576 var_to_reg_int(s1, src, REG_ITMP1);
2577 if (iptr->val.l == 0) {
2581 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2582 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2585 LCONST(REG_ITMP2, iptr->val.l);
2586 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2588 M_BNEZ(REG_ITMP1, 0);
2590 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2593 case ICMD_IF_LNE: /* ..., value ==> ... */
2594 /* op1 = target JavaVM pc, val.l = constant */
2596 var_to_reg_int(s1, src, REG_ITMP1);
2597 if (iptr->val.l == 0) {
2601 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2602 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2605 LCONST(REG_ITMP2, iptr->val.l);
2606 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2608 M_BEQZ(REG_ITMP1, 0);
2610 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2613 case ICMD_IF_LGT: /* ..., value ==> ... */
2614 /* op1 = target JavaVM pc, val.l = constant */
2616 var_to_reg_int(s1, src, REG_ITMP1);
2617 if (iptr->val.l == 0) {
2621 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2622 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2625 LCONST(REG_ITMP2, iptr->val.l);
2626 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2628 M_BEQZ(REG_ITMP1, 0);
2630 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2633 case ICMD_IF_LGE: /* ..., value ==> ... */
2634 /* op1 = target JavaVM pc, val.l = constant */
2636 var_to_reg_int(s1, src, REG_ITMP1);
2637 if (iptr->val.l == 0) {
2641 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2642 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2645 LCONST(REG_ITMP2, iptr->val.l);
2646 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2648 M_BEQZ(REG_ITMP1, 0);
2650 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2653 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2654 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2655 case ICMD_IF_ACMPEQ:
2657 var_to_reg_int(s1, src->prev, REG_ITMP1);
2658 var_to_reg_int(s2, src, REG_ITMP2);
2659 M_CMPEQ(s1, s2, REG_ITMP1);
2660 M_BNEZ(REG_ITMP1, 0);
2661 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2664 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2665 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2666 case ICMD_IF_ACMPNE:
2668 var_to_reg_int(s1, src->prev, REG_ITMP1);
2669 var_to_reg_int(s2, src, REG_ITMP2);
2670 M_CMPEQ(s1, s2, REG_ITMP1);
2671 M_BEQZ(REG_ITMP1, 0);
2672 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2675 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2676 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2678 var_to_reg_int(s1, src->prev, REG_ITMP1);
2679 var_to_reg_int(s2, src, REG_ITMP2);
2680 M_CMPLT(s1, s2, REG_ITMP1);
2681 M_BNEZ(REG_ITMP1, 0);
2682 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2685 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2686 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2688 var_to_reg_int(s1, src->prev, REG_ITMP1);
2689 var_to_reg_int(s2, src, REG_ITMP2);
2690 M_CMPLE(s1, s2, REG_ITMP1);
2691 M_BEQZ(REG_ITMP1, 0);
2692 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2695 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2696 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2698 var_to_reg_int(s1, src->prev, REG_ITMP1);
2699 var_to_reg_int(s2, src, REG_ITMP2);
2700 M_CMPLE(s1, s2, REG_ITMP1);
2701 M_BNEZ(REG_ITMP1, 0);
2702 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2705 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2706 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2708 var_to_reg_int(s1, src->prev, REG_ITMP1);
2709 var_to_reg_int(s2, src, REG_ITMP2);
2710 M_CMPLT(s1, s2, REG_ITMP1);
2711 M_BEQZ(REG_ITMP1, 0);
2712 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2715 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2717 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2720 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2721 /* val.i = constant */
2723 var_to_reg_int(s1, src, REG_ITMP1);
2724 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2726 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2727 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2728 M_CMPEQ(s1, REG_ZERO, d);
2729 store_reg_to_var_int(iptr->dst, d);
2732 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2733 M_CMPEQ(s1, REG_ZERO, d);
2735 store_reg_to_var_int(iptr->dst, d);
2739 M_MOV(s1, REG_ITMP1);
2742 ICONST(d, iptr[1].val.i);
2744 if ((s3 >= 0) && (s3 <= 255)) {
2745 M_CMOVEQ_IMM(s1, s3, d);
2748 ICONST(REG_ITMP2, s3);
2749 M_CMOVEQ(s1, REG_ITMP2, d);
2751 store_reg_to_var_int(iptr->dst, d);
2754 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2755 /* val.i = constant */
2757 var_to_reg_int(s1, src, REG_ITMP1);
2758 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2760 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2761 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2762 M_CMPEQ(s1, REG_ZERO, d);
2763 store_reg_to_var_int(iptr->dst, d);
2766 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2767 M_CMPEQ(s1, REG_ZERO, d);
2769 store_reg_to_var_int(iptr->dst, d);
2773 M_MOV(s1, REG_ITMP1);
2776 ICONST(d, iptr[1].val.i);
2778 if ((s3 >= 0) && (s3 <= 255)) {
2779 M_CMOVNE_IMM(s1, s3, d);
2782 ICONST(REG_ITMP2, s3);
2783 M_CMOVNE(s1, REG_ITMP2, d);
2785 store_reg_to_var_int(iptr->dst, d);
2788 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2789 /* val.i = constant */
2791 var_to_reg_int(s1, src, REG_ITMP1);
2792 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2794 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2795 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2796 M_CMPLT(s1, REG_ZERO, d);
2797 store_reg_to_var_int(iptr->dst, d);
2800 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2801 M_CMPLE(REG_ZERO, s1, d);
2802 store_reg_to_var_int(iptr->dst, d);
2806 M_MOV(s1, REG_ITMP1);
2809 ICONST(d, iptr[1].val.i);
2811 if ((s3 >= 0) && (s3 <= 255)) {
2812 M_CMOVLT_IMM(s1, s3, d);
2815 ICONST(REG_ITMP2, s3);
2816 M_CMOVLT(s1, REG_ITMP2, d);
2818 store_reg_to_var_int(iptr->dst, d);
2821 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2822 /* val.i = constant */
2824 var_to_reg_int(s1, src, REG_ITMP1);
2825 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2827 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2828 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2829 M_CMPLE(REG_ZERO, s1, d);
2830 store_reg_to_var_int(iptr->dst, d);
2833 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2834 M_CMPLT(s1, REG_ZERO, d);
2835 store_reg_to_var_int(iptr->dst, d);
2839 M_MOV(s1, REG_ITMP1);
2842 ICONST(d, iptr[1].val.i);
2844 if ((s3 >= 0) && (s3 <= 255)) {
2845 M_CMOVGE_IMM(s1, s3, d);
2848 ICONST(REG_ITMP2, s3);
2849 M_CMOVGE(s1, REG_ITMP2, d);
2851 store_reg_to_var_int(iptr->dst, d);
2854 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2855 /* val.i = constant */
2857 var_to_reg_int(s1, src, REG_ITMP1);
2858 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2860 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2861 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2862 M_CMPLT(REG_ZERO, s1, d);
2863 store_reg_to_var_int(iptr->dst, d);
2866 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2867 M_CMPLE(s1, REG_ZERO, d);
2868 store_reg_to_var_int(iptr->dst, d);
2872 M_MOV(s1, REG_ITMP1);
2875 ICONST(d, iptr[1].val.i);
2877 if ((s3 >= 0) && (s3 <= 255)) {
2878 M_CMOVGT_IMM(s1, s3, d);
2881 ICONST(REG_ITMP2, s3);
2882 M_CMOVGT(s1, REG_ITMP2, d);
2884 store_reg_to_var_int(iptr->dst, d);
2887 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2888 /* val.i = constant */
2890 var_to_reg_int(s1, src, REG_ITMP1);
2891 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
2893 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2894 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2895 M_CMPLE(s1, REG_ZERO, d);
2896 store_reg_to_var_int(iptr->dst, d);
2899 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2900 M_CMPLT(REG_ZERO, s1, d);
2901 store_reg_to_var_int(iptr->dst, d);
2905 M_MOV(s1, REG_ITMP1);
2908 ICONST(d, iptr[1].val.i);
2910 if ((s3 >= 0) && (s3 <= 255)) {
2911 M_CMOVLE_IMM(s1, s3, d);
2914 ICONST(REG_ITMP2, s3);
2915 M_CMOVLE(s1, REG_ITMP2, d);
2917 store_reg_to_var_int(iptr->dst, d);
2921 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2925 var_to_reg_int(s1, src, REG_RESULT);
2926 M_INTMOVE(s1, REG_RESULT);
2928 goto nowperformreturn;
2930 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2933 var_to_reg_flt(s1, src, REG_FRESULT);
2934 M_FLTMOVE(s1, REG_FRESULT);
2936 goto nowperformreturn;
2938 case ICMD_RETURN: /* ... ==> ... */
2944 p = parentargs_base;
2946 /* call trace function */
2949 M_LDA(REG_SP, REG_SP, -3 * 8);
2950 M_AST(REG_RA, REG_SP, 0 * 8);
2951 M_LST(REG_RESULT, REG_SP, 1 * 8);
2952 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2953 a = dseg_addaddress(cd, m);
2954 M_ALD(rd->argintregs[0], REG_PV, a);
2955 M_MOV(REG_RESULT, rd->argintregs[1]);
2956 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2957 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2958 a = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2959 M_ALD(REG_PV, REG_PV, a);
2960 M_JSR(REG_RA, REG_PV);
2961 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2962 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
2964 s4 ml = -s1, mh = 0;
2965 while (ml < -32768) { ml += 65536; mh--; }
2966 M_LDA(REG_PV, REG_RA, ml);
2967 M_LDAH(REG_PV, REG_PV, mh);
2969 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2970 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2971 M_ALD(REG_RA, REG_SP, 0 * 8);
2972 M_LDA(REG_SP, REG_SP, 3 * 8);
2975 #if defined(USE_THREADS)
2976 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2979 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2981 switch (iptr->opc) {
2985 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2989 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2993 a = dseg_addaddress(cd, BUILTIN_monitorexit);
2994 M_ALD(REG_PV, REG_PV, a);
2995 M_JSR(REG_RA, REG_PV);
2996 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2997 M_LDA(REG_PV, REG_RA, disp);
2999 switch (iptr->opc) {
3003 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
3007 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
3013 /* restore return address */
3015 if (!m->isleafmethod) {
3016 p--; M_LLD(REG_RA, REG_SP, p * 8);
3019 /* restore saved registers */
3021 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
3022 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
3024 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
3025 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
3028 /* deallocate stack */
3030 if (parentargs_base) {
3031 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
3034 M_RET(REG_ZERO, REG_RA);
3040 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3045 tptr = (void **) iptr->target;
3047 s4ptr = iptr->val.a;
3048 l = s4ptr[1]; /* low */
3049 i = s4ptr[2]; /* high */
3051 var_to_reg_int(s1, src, REG_ITMP1);
3053 {M_INTMOVE(s1, REG_ITMP1);}
3054 else if (l <= 32768) {
3055 M_LDA(REG_ITMP1, s1, -l);
3058 ICONST(REG_ITMP2, l);
3059 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3066 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3068 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3069 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3071 M_BEQZ(REG_ITMP2, 0);
3074 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[0]), mcodeptr); */
3075 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3077 /* build jump table top down and use address of lowest entry */
3079 /* s4ptr += 3 + i; */
3083 /* dseg_addtarget(cd, BlockPtrOfPC(*--s4ptr)); */
3084 dseg_addtarget(cd, (basicblock *) tptr[0]);
3089 /* length of dataseg after last dseg_addtarget is used by load */
3091 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3092 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3093 M_JMP(REG_ZERO, REG_ITMP2);
3098 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3100 s4 i, l, val, *s4ptr;
3103 tptr = (void **) iptr->target;
3105 s4ptr = iptr->val.a;
3106 l = s4ptr[0]; /* default */
3107 i = s4ptr[1]; /* count */
3109 MCODECHECK((i<<2)+8);
3110 var_to_reg_int(s1, src, REG_ITMP1);
3116 if ((val >= 0) && (val <= 255)) {
3117 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3120 if ((val >= -32768) && (val <= 32767)) {
3121 M_LDA(REG_ITMP2, REG_ZERO, val);
3124 a = dseg_adds4(cd, val);
3125 M_ILD(REG_ITMP2, REG_PV, a);
3127 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3129 M_BNEZ(REG_ITMP2, 0);
3130 /* codegen_addreference(cd, BlockPtrOfPC(s4ptr[1]), mcodeptr); */
3131 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3135 /* codegen_addreference(cd, BlockPtrOfPC(l), mcodeptr); */
3137 tptr = (void **) iptr->target;
3138 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3145 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3146 /* op1 = arg count val.a = builtintable entry */
3152 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3153 /* op1 = arg count, val.a = method pointer */
3155 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3156 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3157 case ICMD_INVOKEINTERFACE:
3162 md = lm->parseddesc;
3164 unresolved_method *um = iptr->target;
3165 md = um->methodref->parseddesc.md;
3171 MCODECHECK((s3 << 1) + 64);
3173 /* copy arguments to registers or stack location */
3175 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3176 if (src->varkind == ARGVAR)
3178 if (IS_INT_LNG_TYPE(src->type)) {
3179 if (!md->params[s3].inmemory) {
3180 s1 = rd->argintregs[md->params[s3].regoff];
3181 var_to_reg_int(d, src, s1);
3184 var_to_reg_int(d, src, REG_ITMP1);
3185 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3189 if (!md->params[s3].inmemory) {
3190 s1 = rd->argfltregs[md->params[s3].regoff];
3191 var_to_reg_flt(d, src, s1);
3194 var_to_reg_flt(d, src, REG_FTMP1);
3195 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3200 switch (iptr->opc) {
3203 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target);
3205 if (opt_showdisassemble)
3211 a = (ptrint) bte->fp;
3214 a = dseg_addaddress(cd, a);
3215 d = md->returntype.type;
3217 M_ALD(REG_PV, REG_PV, a); /* Pointer to built-in-function */
3220 case ICMD_INVOKESPECIAL:
3221 M_BEQZ(rd->argintregs[0], 0);
3222 codegen_addxnullrefs(cd, mcodeptr);
3225 case ICMD_INVOKESTATIC:
3227 unresolved_method *um = iptr->target;
3229 codegen_addpatchref(cd, mcodeptr,
3230 PATCHER_invokestatic_special, um);
3232 if (opt_showdisassemble)
3236 d = um->methodref->parseddesc.md->returntype.type;
3239 a = (ptrint) lm->stubroutine;
3240 d = lm->parseddesc->returntype.type;
3243 a = dseg_addaddress(cd, a);
3244 M_ALD(REG_PV, REG_PV, a); /* method pointer in r27 */
3247 case ICMD_INVOKEVIRTUAL:
3248 gen_nullptr_check(rd->argintregs[0]);
3251 unresolved_method *um = iptr->target;
3253 codegen_addpatchref(cd, mcodeptr,
3254 PATCHER_invokevirtual, um);
3256 if (opt_showdisassemble)
3260 d = um->methodref->parseddesc.md->returntype.type;
3263 s1 = OFFSET(vftbl_t, table[0]) +
3264 sizeof(methodptr) * lm->vftblindex;
3265 d = lm->parseddesc->returntype.type;
3268 M_ALD(REG_METHODPTR, rd->argintregs[0],
3269 OFFSET(java_objectheader, vftbl));
3270 M_ALD(REG_PV, REG_METHODPTR, s1);
3273 case ICMD_INVOKEINTERFACE:
3274 gen_nullptr_check(rd->argintregs[0]);
3277 unresolved_method *um = iptr->target;
3279 codegen_addpatchref(cd, mcodeptr,
3280 PATCHER_invokeinterface, um);
3282 if (opt_showdisassemble)
3287 d = um->methodref->parseddesc.md->returntype.type;
3290 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3291 sizeof(methodptr*) * lm->class->index;
3293 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3295 d = lm->parseddesc->returntype.type;
3298 M_ALD(REG_METHODPTR, rd->argintregs[0],
3299 OFFSET(java_objectheader, vftbl));
3300 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3301 M_ALD(REG_PV, REG_METHODPTR, s2);
3305 M_JSR(REG_RA, REG_PV);
3309 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3310 if (s1 <= 32768) M_LDA(REG_PV, REG_RA, -s1);
3312 s4 ml = -s1, mh = 0;
3313 while (ml < -32768) { ml += 65536; mh--; }
3314 M_LDA(REG_PV, REG_RA, ml);
3315 M_LDAH(REG_PV, REG_PV, mh);
3318 /* d contains return type */
3320 if (d != TYPE_VOID) {
3321 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3322 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3323 M_INTMOVE(REG_RESULT, s1);
3324 store_reg_to_var_int(iptr->dst, s1);
3326 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3327 M_FLTMOVE(REG_FRESULT, s1);
3328 store_reg_to_var_flt(iptr->dst, s1);
3334 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3336 /* op1: 0 == array, 1 == class */
3337 /* val.a: (classinfo*) superclass */
3339 /* superclass is an interface:
3341 * OK if ((sub == NULL) ||
3342 * (sub->vftbl->interfacetablelength > super->index) &&
3343 * (sub->vftbl->interfacetable[-super->index] != NULL));
3345 * superclass is a class:
3347 * OK if ((sub == NULL) || (0
3348 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3349 * super->vftbl->diffval));
3354 vftbl_t *supervftbl;
3357 super = (classinfo *) iptr->val.a;
3364 superindex = super->index;
3365 supervftbl = super->vftbl;
3368 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3369 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3371 var_to_reg_int(s1, src, REG_ITMP1);
3373 /* calculate interface checkcast code size */
3377 s2 += opt_showdisassemble ? 1 : 0;
3379 /* calculate class checkcast code size */
3381 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3383 s3 += opt_showdisassemble ? 1 : 0;
3385 /* if class is not resolved, check which code to call */
3388 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3390 codegen_addpatchref(cd, mcodeptr,
3391 PATCHER_checkcast_instanceof_flags,
3392 (constant_classref *) iptr->target);
3394 if (opt_showdisassemble)
3397 a = dseg_adds4(cd, 0); /* super->flags */
3398 M_ILD(REG_ITMP2, REG_PV, a);
3399 a = dseg_adds4(cd, ACC_INTERFACE);
3400 M_ILD(REG_ITMP3, REG_PV, a);
3401 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3402 M_BEQZ(REG_ITMP2, s2 + 1);
3405 /* interface checkcast code */
3407 if (!super || (super->flags & ACC_INTERFACE)) {
3412 codegen_addpatchref(cd, mcodeptr,
3413 PATCHER_checkcast_instanceof_interface,
3414 (constant_classref *) iptr->target);
3416 if (opt_showdisassemble)
3420 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3421 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, interfacetablelength));
3422 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3423 M_BLEZ(REG_ITMP3, 0);
3424 codegen_addxcastrefs(cd, mcodeptr);
3425 M_ALD(REG_ITMP3, REG_ITMP2,
3426 OFFSET(vftbl_t, interfacetable[0]) -
3427 superindex * sizeof(methodptr*));
3428 M_BEQZ(REG_ITMP3, 0);
3429 codegen_addxcastrefs(cd, mcodeptr);
3435 /* class checkcast code */
3437 if (!super || !(super->flags & ACC_INTERFACE)) {
3442 codegen_addpatchref(cd, mcodeptr,
3443 PATCHER_checkcast_instanceof_class,
3444 (constant_classref *) iptr->target);
3446 if (opt_showdisassemble)
3450 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3451 a = dseg_addaddress(cd, supervftbl);
3452 M_ALD(REG_ITMP3, REG_PV, a);
3453 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3454 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3456 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3457 /* if (s1 != REG_ITMP1) { */
3458 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3459 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3460 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3461 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3463 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3466 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3467 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3468 M_ALD(REG_ITMP3, REG_PV, a);
3469 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3470 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3471 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3474 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3475 M_BEQZ(REG_ITMP3, 0);
3476 codegen_addxcastrefs(cd, mcodeptr);
3478 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
3480 store_reg_to_var_int(iptr->dst, d);
3484 case ICMD_ARRAYCHECKCAST: /* ..., objectref ==> ..., objectref */
3485 /* op1: 1... resolved, 0... not resolved */
3487 var_to_reg_int(s1, src, rd->argintregs[0]);
3488 M_INTMOVE(s1, rd->argintregs[0]);
3493 codegen_addpatchref(cd, mcodeptr, bte->fp, iptr->target);
3495 if (opt_showdisassemble)
3501 a = (ptrint) bte->fp;
3504 disp = dseg_addaddress(cd, iptr->target);
3505 M_ALD(rd->argintregs[1], REG_PV, disp);
3506 disp = dseg_addaddress(cd, a);
3507 M_ALD(REG_PV, REG_PV, disp);
3508 M_JSR(REG_RA, REG_PV);
3510 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3512 M_LDA(REG_PV, REG_RA, -disp);
3514 s4 ml = -disp, mh = 0;
3515 while (ml < -32768) { ml += 65536; mh--; }
3516 M_LDA(REG_PV, REG_RA, ml);
3517 M_LDAH(REG_PV, REG_PV, mh);
3520 M_BEQZ(REG_RESULT, 0);
3521 codegen_addxcastrefs(cd, mcodeptr);
3523 var_to_reg_int(s1, src, REG_ITMP1);
3524 d = reg_of_var(rd, iptr->dst, s1);
3526 store_reg_to_var_int(iptr->dst, d);
3529 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3531 /* op1: 0 == array, 1 == class */
3532 /* val.a: (classinfo*) superclass */
3534 /* superclass is an interface:
3536 * return (sub != NULL) &&
3537 * (sub->vftbl->interfacetablelength > super->index) &&
3538 * (sub->vftbl->interfacetable[-super->index] != NULL);
3540 * superclass is a class:
3542 * return ((sub != NULL) && (0
3543 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3544 * super->vftbl->diffvall));
3549 vftbl_t *supervftbl;
3552 super = (classinfo *) iptr->val.a;
3559 superindex = super->index;
3560 supervftbl = super->vftbl;
3563 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3564 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3566 var_to_reg_int(s1, src, REG_ITMP1);
3567 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3569 M_MOV(s1, REG_ITMP1);
3573 /* calculate interface instanceof code size */
3577 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3579 /* calculate class instanceof code size */
3583 s3 += (opt_showdisassemble ? 1 : 0);
3585 /* if class is not resolved, check which code to call */
3589 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3591 codegen_addpatchref(cd, mcodeptr,
3592 PATCHER_checkcast_instanceof_flags,
3593 (constant_classref *) iptr->target);
3595 if (opt_showdisassemble)
3598 a = dseg_adds4(cd, 0); /* super->flags */
3599 M_ILD(REG_ITMP3, REG_PV, a);
3600 a = dseg_adds4(cd, ACC_INTERFACE);
3601 M_ILD(REG_ITMP2, REG_PV, a);
3602 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3603 M_BEQZ(REG_ITMP3, s2 + 1);
3606 /* interface instanceof code */
3608 if (!super || (super->flags & ACC_INTERFACE)) {
3614 /* If d == REG_ITMP2, then it's destroyed in check code */
3619 codegen_addpatchref(cd, mcodeptr,
3620 PATCHER_checkcast_instanceof_interface,
3621 (constant_classref *) iptr->target);
3623 if (opt_showdisassemble)
3627 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3628 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3629 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3630 M_BLEZ(REG_ITMP3, 2);
3631 M_ALD(REG_ITMP1, REG_ITMP1,
3632 OFFSET(vftbl_t, interfacetable[0]) -
3633 superindex * sizeof(methodptr*));
3634 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3640 /* class instanceof code */
3642 if (!super || !(super->flags & ACC_INTERFACE)) {
3648 codegen_addpatchref(cd, mcodeptr,
3649 PATCHER_checkcast_instanceof_class,
3650 (constant_classref *) iptr->target);
3652 if (opt_showdisassemble)
3656 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3657 a = dseg_addaddress(cd, supervftbl);
3658 M_ALD(REG_ITMP2, REG_PV, a);
3659 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3660 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3662 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3663 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3664 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3665 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3666 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3668 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3669 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3671 store_reg_to_var_int(iptr->dst, d);
3676 case ICMD_CHECKASIZE: /* ..., size ==> ..., size */
3678 var_to_reg_int(s1, src, REG_ITMP1);
3680 codegen_addxcheckarefs(cd, mcodeptr);
3683 case ICMD_CHECKEXCEPTION: /* ... ==> ... */
3685 M_BEQZ(REG_RESULT, 0);
3686 codegen_addxexceptionrefs(cd, mcodeptr);
3689 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3690 /* op1 = dimension, val.a = array descriptor */
3692 /* check for negative sizes and copy sizes to stack if necessary */
3694 MCODECHECK((iptr->op1 << 1) + 64);
3696 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3697 var_to_reg_int(s2, src, REG_ITMP1);
3699 codegen_addxcheckarefs(cd, mcodeptr);
3701 /* copy SAVEDVAR sizes to stack */
3703 if (src->varkind != ARGVAR) {
3704 M_LST(s2, REG_SP, s1 * 8);
3708 /* is patcher function set? */
3711 codegen_addpatchref(cd, mcodeptr,
3712 (functionptr) iptr->target, iptr->val.a);
3714 if (opt_showdisassemble)
3720 a = (ptrint) iptr->val.a;
3723 /* a0 = dimension count */
3725 ICONST(rd->argintregs[0], iptr->op1);
3727 /* a1 = arraydescriptor */
3729 a = dseg_addaddress(cd, a);
3730 M_ALD(rd->argintregs[1], REG_PV, a);
3732 /* a2 = pointer to dimensions = stack pointer */
3734 M_INTMOVE(REG_SP, rd->argintregs[2]);
3736 a = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3737 M_ALD(REG_PV, REG_PV, a);
3738 M_JSR(REG_RA, REG_PV);
3739 s1 = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3741 M_LDA(REG_PV, REG_RA, -s1);
3743 s4 ml = -s1, mh = 0;
3744 while (ml < -32768) { ml += 65536; mh--; }
3745 M_LDA(REG_PV, REG_RA, ml);
3746 M_LDAH(REG_PV, REG_PV, mh);
3748 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3749 M_INTMOVE(REG_RESULT, s1);
3750 store_reg_to_var_int(iptr->dst, s1);
3754 throw_cacao_exception_exit(string_java_lang_InternalError,
3755 "Unknown ICMD %d", iptr->opc);
3758 } /* for instruction */
3760 /* copy values to interface registers */
3762 src = bptr->outstack;
3763 len = bptr->outdepth;
3770 if ((src->varkind != STACKVAR)) {
3772 if (IS_FLT_DBL_TYPE(s2)) {
3773 var_to_reg_flt(s1, src, REG_FTMP1);
3774 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3775 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3778 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3782 var_to_reg_int(s1, src, REG_ITMP1);
3783 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3784 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3787 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3793 } /* if (bptr -> flags >= BBREACHED) */
3794 } /* for basic block */
3796 codegen_createlinenumbertable(cd);
3800 s4 *xcodeptr = NULL;
3803 /* generate ArithmeticException stubs */
3805 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3806 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3807 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3809 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3813 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3815 (u1 *) mcodeptr - cd->mcodebase);
3819 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3821 if (xcodeptr != NULL) {
3822 M_BR(xcodeptr - mcodeptr - 1);
3825 xcodeptr = mcodeptr;
3827 M_MOV(REG_PV, rd->argintregs[0]);
3828 M_MOV(REG_SP, rd->argintregs[1]);
3829 M_ALD(rd->argintregs[2],
3830 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3831 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3833 M_LDA(REG_SP, REG_SP, -1 * 8);
3834 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3836 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3837 M_ALD(REG_PV, REG_PV, disp);
3838 M_JSR(REG_RA, REG_PV);
3841 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3842 if (disp <= 32768) M_LDA(REG_PV, REG_RA, -disp);
3844 s4 ml = -disp, mh = 0;
3845 while (ml < -32768) { ml += 65536; mh--; }
3846 M_LDA(REG_PV, REG_RA, ml);
3847 M_LDAH(REG_PV, REG_PV, mh);
3850 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3852 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3853 M_LDA(REG_SP, REG_SP, 1 * 8);
3855 disp = dseg_addaddress(cd, asm_handle_exception);
3856 M_ALD(REG_ITMP3, REG_PV, disp);
3857 M_JMP(REG_ZERO, REG_ITMP3);
3861 /* generate ArrayIndexOutOfBoundsException stubs */
3865 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3866 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3868 (u1*) mcodeptr - cd->mcodebase);
3872 /* move index register into REG_ITMP1 */
3874 M_MOV(bref->reg, REG_ITMP1);
3875 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3877 if (xcodeptr != NULL) {
3878 M_BR(xcodeptr - mcodeptr - 1);
3881 xcodeptr = mcodeptr;
3883 M_MOV(REG_PV, rd->argintregs[0]);
3884 M_MOV(REG_SP, rd->argintregs[1]);
3886 if (m->isleafmethod)
3887 M_MOV(REG_RA, rd->argintregs[2]);
3889 M_ALD(rd->argintregs[2],
3890 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3892 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3893 M_MOV(REG_ITMP1, rd->argintregs[4]);
3895 M_LDA(REG_SP, REG_SP, -2 * 8);
3896 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3898 if (m->isleafmethod)
3899 M_AST(REG_RA, REG_SP, 1 * 8);
3901 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3902 M_ALD(REG_PV, REG_PV, disp);
3903 M_JSR(REG_RA, REG_PV);
3906 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3907 if (disp <= 32768) M_LDA(REG_PV, REG_RA, -disp);
3909 s4 ml = -disp, mh = 0;
3910 while (ml < -32768) { ml += 65536; mh--; }
3911 M_LDA(REG_PV, REG_RA, ml);
3912 M_LDAH(REG_PV, REG_PV, mh);
3915 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3917 if (m->isleafmethod)
3918 M_ALD(REG_RA, REG_SP, 1 * 8);
3920 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3921 M_LDA(REG_SP, REG_SP, 2 * 8);
3923 disp = dseg_addaddress(cd, asm_handle_exception);
3924 M_ALD(REG_ITMP3, REG_PV, disp);
3925 M_JMP(REG_ZERO, REG_ITMP3);
3929 /* generate ArrayStoreException stubs */
3933 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3934 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3935 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3937 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
3941 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3943 (u1 *) mcodeptr - cd->mcodebase);
3947 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3949 if (xcodeptr != NULL) {
3950 M_BR(xcodeptr - mcodeptr - 1);
3953 xcodeptr = mcodeptr;
3955 M_MOV(REG_PV, rd->argintregs[0]);
3956 M_MOV(REG_SP, rd->argintregs[1]);
3957 M_ALD(rd->argintregs[2],
3958 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3959 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3961 M_LDA(REG_SP, REG_SP, -1 * 8);
3962 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3964 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3965 M_ALD(REG_PV, REG_PV, disp);
3966 M_JSR(REG_RA, REG_PV);
3969 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3970 if (disp <= 32768) M_LDA(REG_PV, REG_RA, -disp);
3972 s4 ml = -disp, mh = 0;
3973 while (ml < -32768) { ml += 65536; mh--; }
3974 M_LDA(REG_PV, REG_RA, ml);
3975 M_LDAH(REG_PV, REG_PV, mh);
3978 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3980 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3981 M_LDA(REG_SP, REG_SP, 1 * 8);
3983 disp = dseg_addaddress(cd, asm_handle_exception);
3984 M_ALD(REG_ITMP3, REG_PV, disp);
3985 M_JMP(REG_ZERO, REG_ITMP3);
3989 /* generate ClassCastException stubs */
3993 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3994 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
3995 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3997 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4001 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4003 (u1 *) mcodeptr - cd->mcodebase);
4007 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4009 if (xcodeptr != NULL) {
4010 M_BR(xcodeptr - mcodeptr - 1);
4013 xcodeptr = mcodeptr;
4015 M_MOV(REG_PV, rd->argintregs[0]);
4016 M_MOV(REG_SP, rd->argintregs[1]);
4018 if (m->isleafmethod)
4019 M_MOV(REG_RA, rd->argintregs[2]);
4021 M_ALD(rd->argintregs[2],
4022 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4024 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4026 M_LDA(REG_SP, REG_SP, -2 * 8);
4027 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4029 if (m->isleafmethod)
4030 M_AST(REG_RA, REG_SP, 1 * 8);
4032 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
4033 M_ALD(REG_PV, REG_PV, disp);
4034 M_JSR(REG_RA, REG_PV);
4037 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4038 if (disp <= 32768) M_LDA(REG_PV, REG_RA, -disp);
4040 s4 ml = -disp, mh = 0;
4041 while (ml < -32768) { ml += 65536; mh--; }
4042 M_LDA(REG_PV, REG_RA, ml);
4043 M_LDAH(REG_PV, REG_PV, mh);
4046 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4048 if (m->isleafmethod)
4049 M_ALD(REG_RA, REG_SP, 1 * 8);
4051 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4052 M_LDA(REG_SP, REG_SP, 2 * 8);
4054 disp = dseg_addaddress(cd, asm_handle_exception);
4055 M_ALD(REG_ITMP3, REG_PV, disp);
4056 M_JMP(REG_ZERO, REG_ITMP3);
4060 /* generate NegativeArraySizeException stubs */
4064 for (bref = cd->xcheckarefs; bref != NULL; bref = bref->next) {
4065 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4066 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4068 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4072 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4074 (u1 *) mcodeptr - cd->mcodebase);
4078 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4080 if (xcodeptr != NULL) {
4081 M_BR(xcodeptr - mcodeptr - 1);
4084 xcodeptr = mcodeptr;
4086 M_MOV(REG_PV, rd->argintregs[0]);
4087 M_MOV(REG_SP, rd->argintregs[1]);
4088 M_ALD(rd->argintregs[2],
4089 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4090 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4092 M_LDA(REG_SP, REG_SP, -2 * 8);
4093 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4095 disp = dseg_addaddress(cd, stacktrace_inline_negativearraysizeexception);
4096 M_ALD(REG_PV, REG_PV, disp);
4097 M_JSR(REG_RA, REG_PV);
4100 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4101 if (disp <= 32768) M_LDA(REG_PV, REG_RA, -disp);
4103 s4 ml = -disp, mh = 0;
4104 while (ml < -32768) { ml += 65536; mh--; }
4105 M_LDA(REG_PV, REG_RA, ml);
4106 M_LDAH(REG_PV, REG_PV, mh);
4109 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4111 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4112 M_LDA(REG_SP, REG_SP, 2 * 8);
4114 disp = dseg_addaddress(cd, asm_handle_exception);
4115 M_ALD(REG_ITMP3, REG_PV, disp);
4116 M_JMP(REG_ZERO, REG_ITMP3);
4120 /* generate NullPointerException stubs */
4124 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
4125 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4126 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4128 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4132 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4134 (u1 *) mcodeptr - cd->mcodebase);
4138 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4140 if (xcodeptr != NULL) {
4141 M_BR(xcodeptr - mcodeptr - 1);
4144 xcodeptr = mcodeptr;
4146 M_MOV(REG_PV, rd->argintregs[0]);
4147 M_MOV(REG_SP, rd->argintregs[1]);
4149 if (m->isleafmethod)
4150 M_MOV(REG_RA, rd->argintregs[2]);
4152 M_ALD(rd->argintregs[2],
4153 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4155 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4157 M_LDA(REG_SP, REG_SP, -2 * 8);
4158 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4160 if (m->isleafmethod)
4161 M_AST(REG_RA, REG_SP, 1 * 8);
4163 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
4164 M_ALD(REG_PV, REG_PV, disp);
4165 M_JSR(REG_RA, REG_PV);
4168 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4169 if (disp <= 32768) M_LDA(REG_PV, REG_RA, -disp);
4171 s4 ml = -disp, mh = 0;
4172 while (ml < -32768) { ml += 65536; mh--; }
4173 M_LDA(REG_PV, REG_RA, ml);
4174 M_LDAH(REG_PV, REG_PV, mh);
4177 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4179 if (m->isleafmethod)
4180 M_ALD(REG_RA, REG_SP, 1 * 8);
4182 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4183 M_LDA(REG_SP, REG_SP, 2 * 8);
4185 disp = dseg_addaddress(cd, asm_handle_exception);
4186 M_ALD(REG_ITMP3, REG_PV, disp);
4187 M_JMP(REG_ZERO, REG_ITMP3);
4191 /* generate ICMD_CHECKEXCEPTION stubs */
4195 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4196 if ((cd->exceptiontablelength == 0) && (xcodeptr != NULL)) {
4197 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4199 (u1 *) xcodeptr - (u1 *) cd->mcodebase - 4);
4203 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4205 (u1 *) mcodeptr - cd->mcodebase);
4209 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4211 if (xcodeptr != NULL) {
4212 M_BR(xcodeptr - mcodeptr - 1);
4215 xcodeptr = mcodeptr;
4217 M_MOV(REG_PV, rd->argintregs[0]);
4218 M_MOV(REG_SP, rd->argintregs[1]);
4219 M_ALD(rd->argintregs[2],
4220 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4221 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4223 M_LDA(REG_SP, REG_SP, -1 * 8);
4224 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4226 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4227 M_ALD(REG_PV, REG_PV, disp);
4228 M_JSR(REG_RA, REG_PV);
4231 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4232 if (disp <= 32768) M_LDA(REG_PV, REG_RA, -disp);
4234 s4 ml = -disp, mh = 0;
4235 while (ml < -32768) { ml += 65536; mh--; }
4236 M_LDA(REG_PV, REG_RA, ml);
4237 M_LDAH(REG_PV, REG_PV, mh);
4240 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4242 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4243 M_LDA(REG_SP, REG_SP, 1 * 8);
4245 disp = dseg_addaddress(cd, asm_handle_exception);
4246 M_ALD(REG_ITMP3, REG_PV, disp);
4247 M_JMP(REG_ZERO, REG_ITMP3);
4251 /* generate patcher stub call code */
4258 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4259 /* check code segment size */
4261 MCODECHECK(13 + 4 + 1);
4263 /* Get machine code which is patched back in later. The call is */
4264 /* 1 instruction word long. */
4266 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4269 /* patch in the call to call the following code (done at compile */
4272 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4273 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4275 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4277 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4279 /* create stack frame */
4281 M_LSUB_IMM(REG_SP, 5 * 8, REG_SP);
4283 /* move return address onto stack */
4285 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4287 /* move pointer to java_objectheader onto stack */
4289 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4290 /* create a virtual java_objectheader */
4292 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4293 a = dseg_addaddress(cd, NULL); /* vftbl */
4296 M_LDA(REG_ITMP3, REG_PV, a);
4298 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4299 M_LDA(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4301 M_AST(REG_ITMP3, REG_SP, 3 * 8);
4303 M_AST(REG_ZERO, REG_SP, 3 * 8);
4306 /* move machine code onto stack */
4308 a = dseg_adds4(cd, mcode);
4310 M_ILD(REG_ITMP3, REG_PV, a);
4312 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4313 M_ILD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4315 M_IST(REG_ITMP3, REG_SP, 2 * 8);
4317 /* move class/method/field reference onto stack */
4319 a = dseg_addaddress(cd, pref->ref);
4321 M_ALD(REG_ITMP3, REG_PV, a);
4323 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4324 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4326 M_AST(REG_ITMP3, REG_SP, 1 * 8);
4328 /* move patcher function pointer onto stack */
4330 a = dseg_addaddress(cd, pref->patcher);
4332 M_ALD(REG_ITMP3, REG_PV, a);
4334 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4335 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4337 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4339 a = dseg_addaddress(cd, asm_wrapper_patcher);
4341 M_ALD(REG_ITMP3, REG_PV, a);
4343 M_LDAH(REG_ITMP3, REG_PV, (a >> 16) & 0x0000ffff);
4344 M_ALD(REG_ITMP3, REG_ITMP3, a & 0x0000ffff);
4346 M_JMP(REG_ZERO, REG_ITMP3);
4351 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4355 /* createcompilerstub **********************************************************
4357 Creates a stub routine which calls the compiler.
4359 *******************************************************************************/
4361 #define COMPSTUBSIZE 3
4363 functionptr createcompilerstub(methodinfo *m)
4365 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4366 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4368 /* code for the stub */
4369 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4370 M_JMP(0, REG_PV); /* jump to the compiler, return address
4371 in reg 0 is used as method pointer */
4372 s[1] = (ptrint) m; /* literals to be adressed */
4373 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4375 #if defined(STATISTICS)
4377 count_cstub_len += COMPSTUBSIZE * 8;
4380 return (functionptr) s;
4384 /* createnativestub ************************************************************
4386 Creates a stub routine which calls a native method.
4388 *******************************************************************************/
4390 functionptr createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4391 registerdata *rd, methoddesc *nmd)
4393 s4 *mcodeptr; /* code generation pointer */
4394 s4 stackframesize; /* size of stackframe if needed */
4398 s4 i, j; /* count variables */
4402 /* initialize variables */
4405 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4408 /* calculate stack frame size */
4411 1 + /* return address */
4412 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4413 1 + /* methodinfo for call trace */
4414 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4418 /* create method header */
4420 (void) dseg_addaddress(cd, m); /* MethodPointer */
4421 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4422 (void) dseg_adds4(cd, 0); /* IsSync */
4423 (void) dseg_adds4(cd, 0); /* IsLeaf */
4424 (void) dseg_adds4(cd, 0); /* IntSave */
4425 (void) dseg_adds4(cd, 0); /* FltSave */
4426 (void) dseg_addlinenumbertablesize(cd);
4427 (void) dseg_adds4(cd, 0); /* ExTableSize */
4430 /* initialize mcode variables */
4432 mcodeptr = (s4 *) cd->mcodebase;
4433 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
4436 /* generate stub code */
4438 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4439 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4442 /* if function is static, check for initialized */
4444 if ((m->flags & ACC_STATIC) && !m->class->initialized) {
4445 codegen_addpatchref(cd, mcodeptr, PATCHER_clinit, m->class);
4447 if (opt_showdisassemble)
4451 /* call trace function */
4454 /* save integer argument registers */
4456 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++)
4457 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4458 M_LST(rd->argintregs[i], REG_SP, j++ * 8);
4460 /* save and copy float arguments into integer registers */
4462 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4463 t = md->paramtypes[i].type;
4465 if (IS_FLT_DBL_TYPE(t)) {
4466 if (IS_2_WORD_TYPE(t)) {
4467 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4468 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4470 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4471 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4477 off = dseg_addaddress(cd, m);
4478 M_ALD(REG_ITMP1, REG_PV, off);
4479 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4480 off = dseg_addaddress(cd, builtin_trace_args);
4481 M_ALD(REG_PV, REG_PV, off);
4482 M_JSR(REG_RA, REG_PV);
4483 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4484 M_LDA(REG_PV, REG_RA, -disp);
4486 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++)
4487 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4488 M_LLD(rd->argintregs[i], REG_SP, j++ * 8);
4490 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4491 t = md->paramtypes[i].type;
4493 if (IS_FLT_DBL_TYPE(t)) {
4494 if (IS_2_WORD_TYPE(t)) {
4495 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4497 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4505 /* save integer and float argument registers */
4507 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4508 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4509 M_LST(rd->argintregs[i], REG_SP, j++ * 8);
4511 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++)
4512 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type))
4513 M_DST(rd->argfltregs[i], REG_SP, j++ * 8);
4515 /* create native stackframe info */
4517 M_AADD_IMM(REG_SP, stackframesize * 8 - sizeof(stackframeinfo),
4519 M_MOV(REG_PV, rd->argintregs[1]);
4520 M_AADD_IMM(REG_SP, stackframesize * 8, rd->argintregs[2]);
4521 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4522 off = dseg_addaddress(cd, stacktrace_create_native_stackframeinfo);
4523 M_ALD(REG_PV, REG_PV, off);
4524 M_JSR(REG_RA, REG_PV);
4525 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4526 M_LDA(REG_PV, REG_RA, -disp);
4528 /* restore integer and float argument registers */
4530 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++)
4531 if (IS_INT_LNG_TYPE(md->paramtypes[i].type))
4532 M_LLD(rd->argintregs[i], REG_SP, j++ * 8);
4534 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++)
4535 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type))
4536 M_DLD(rd->argfltregs[i], REG_SP, j++ * 8);
4539 /* copy or spill arguments to new locations */
4541 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4542 t = md->paramtypes[i].type;
4544 if (IS_INT_LNG_TYPE(t)) {
4545 if (!md->params[i].inmemory) {
4546 s1 = rd->argintregs[md->params[i].regoff];
4548 if (!nmd->params[j].inmemory) {
4549 s2 = rd->argintregs[nmd->params[j].regoff];
4553 s2 = nmd->params[j].regoff;
4554 M_LST(s1, REG_SP, s2 * 8);
4558 s1 = md->params[i].regoff + stackframesize;
4559 s2 = nmd->params[j].regoff;
4560 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4561 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4565 if (!md->params[i].inmemory) {
4566 s1 = rd->argfltregs[md->params[i].regoff];
4568 if (!nmd->params[j].inmemory) {
4569 s2 = rd->argfltregs[nmd->params[j].regoff];
4573 s2 = nmd->params[j].regoff;
4574 if (IS_2_WORD_TYPE(t))
4575 M_DST(s1, REG_SP, s2 * 8);
4577 M_FST(s1, REG_SP, s2 * 8);
4581 s1 = md->params[i].regoff + stackframesize;
4582 s2 = nmd->params[j].regoff;
4583 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4584 if (IS_2_WORD_TYPE(t))
4585 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4587 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4592 /* put class into second argument register */
4594 if (m->flags & ACC_STATIC) {
4595 off = dseg_addaddress(cd, m->class);
4596 M_ALD(rd->argintregs[1], REG_PV, off);
4599 /* put env into first argument register */
4601 off = dseg_addaddress(cd, &env);
4602 M_ALD(rd->argintregs[0], REG_PV, off);
4604 /* do the native function call */
4606 #if !defined(ENABLE_STATICVM)
4608 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m);
4610 if (opt_showdisassemble)
4615 off = dseg_addaddress(cd, f);
4616 M_ALD(REG_PV, REG_PV, off); /* load adress of native method */
4617 M_JSR(REG_RA, REG_PV); /* call native method */
4618 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4619 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4622 /* remove native stackframe info */
4624 if (IS_INT_LNG_TYPE(md->returntype.type))
4625 M_LST(REG_RESULT, REG_SP, 0 * 8);
4627 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4629 M_AADD_IMM(REG_SP, stackframesize * 8 - sizeof(stackframeinfo),
4631 off = dseg_addaddress(cd, stacktrace_remove_stackframeinfo);
4632 M_ALD(REG_PV, REG_PV, off);
4633 M_JSR(REG_RA, REG_PV);
4634 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4635 M_LDA(REG_PV, REG_RA, -disp);
4637 if (IS_INT_LNG_TYPE(md->returntype.type))
4638 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4640 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4643 /* call finished trace */
4646 M_LST(REG_RESULT, REG_SP, 0 * 8);
4647 M_DST(REG_FRESULT, REG_SP, 1 * 8);
4649 off = dseg_addaddress(cd, m);
4650 M_ALD(rd->argintregs[0], REG_PV, off);
4652 M_MOV(REG_RESULT, rd->argintregs[1]);
4653 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4654 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4656 off = dseg_addaddress(cd, builtin_displaymethodstop);
4657 M_ALD(REG_PV, REG_PV, off);
4658 M_JSR(REG_RA, REG_PV);
4659 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4660 M_LDA(REG_PV, REG_RA, -disp);
4662 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4663 M_DLD(REG_FRESULT, REG_SP, 1 * 8);
4667 /* check for exception */
4669 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4670 if (IS_FLT_DBL_TYPE(md->returntype.type))
4671 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4673 M_AST(REG_RESULT, REG_SP, 0 * 8);
4675 off = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4676 M_ALD(REG_PV, REG_PV, off);
4677 M_JSR(REG_RA, REG_PV);
4678 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4679 M_LDA(REG_PV, REG_RA, -disp);
4680 M_MOV(REG_RESULT, REG_ITMP3);
4682 if (IS_FLT_DBL_TYPE(md->returntype.type))
4683 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4685 M_ALD(REG_RESULT, REG_SP, 0 * 8);
4687 off = dseg_addaddress(cd, &_exceptionptr);
4688 M_ALD(REG_ITMP3, REG_PV, off); /* get address of exceptionptr */
4691 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4692 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4694 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4696 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4698 M_RET(REG_ZERO, REG_RA); /* return to caller */
4700 /* handle exception */
4702 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4704 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4705 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4707 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4709 off = dseg_addaddress(cd, asm_handle_nat_exception);
4710 M_ALD(REG_ITMP3, REG_PV, off); /* load asm exception handler address */
4711 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4714 /* process patcher calls **************************************************/
4722 /* there can only be one <clinit> ref entry */
4723 pref = cd->patchrefs;
4725 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4726 /* Get machine code which is patched back in later. The call is */
4727 /* 1 instruction word long. */
4729 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4730 mcode = (u4) *xcodeptr;
4732 /* patch in the call to call the following code (done at compile */
4735 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4736 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4738 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4740 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4742 /* create stack frame */
4744 M_LSUB_IMM(REG_SP, 5 * 8, REG_SP);
4746 /* move return address onto stack */
4748 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4750 /* move pointer to java_objectheader onto stack */
4752 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4753 /* create a virtual java_objectheader */
4755 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4756 off = dseg_addaddress(cd, NULL); /* vftbl */
4758 M_LDA(REG_ITMP3, REG_PV, off);
4759 M_AST(REG_ITMP3, REG_SP, 3 * 8);
4761 M_AST(REG_ZERO, REG_SP, 3 * 8);
4764 /* move machine code onto stack */
4766 off = dseg_adds4(cd, mcode);
4767 M_ILD(REG_ITMP3, REG_PV, off);
4768 M_IST(REG_ITMP3, REG_SP, 2 * 8);
4770 /* move class/method/field reference onto stack */
4772 off = dseg_addaddress(cd, pref->ref);
4773 M_ALD(REG_ITMP3, REG_PV, off);
4774 M_AST(REG_ITMP3, REG_SP, 1 * 8);
4776 /* move patcher function pointer onto stack */
4778 off = dseg_addaddress(cd, pref->patcher);
4779 M_ALD(REG_ITMP3, REG_PV, off);
4780 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4782 off = dseg_addaddress(cd, asm_wrapper_patcher);
4783 M_ALD(REG_ITMP3, REG_PV, off);
4784 M_JMP(REG_ZERO, REG_ITMP3);
4788 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4790 return m->entrypoint;
4795 * These are local overrides for various environment variables in Emacs.
4796 * Please do not remove this and leave it at the end of the file, where
4797 * Emacs will automagically detect them.
4798 * ---------------------------------------------------------------------
4801 * indent-tabs-mode: t