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
35 $Id: codegen.c 3921 2005-12-08 23:12:01Z twisti $
49 #include "vm/jit/alpha/arch.h"
50 #include "vm/jit/alpha/codegen.h"
52 #include "cacao/cacao.h"
53 #include "native/jni.h"
54 #include "native/native.h"
55 #include "vm/builtin.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/stringlocal.h"
59 #include "vm/jit/asmpart.h"
60 #include "vm/jit/codegen.inc"
61 #include "vm/jit/jit.h"
64 # include "vm/jit/lsra.h"
65 # include "vm/jit/lsra.inc"
68 #include "vm/jit/parse.h"
69 #include "vm/jit/patcher.h"
70 #include "vm/jit/reg.h"
71 #include "vm/jit/reg.inc"
74 /* codegen *********************************************************************
76 Generates machine code.
78 *******************************************************************************/
80 bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
82 s4 len, s1, s2, s3, d, disp;
91 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
92 builtintable_entry *bte;
95 /* prevent compiler warnings */
106 savedregs_num = (m->isleafmethod) ? 0 : 1; /* space to save the RA */
108 /* space to save used callee saved registers */
110 savedregs_num += (INT_SAV_CNT - rd->savintreguse);
111 savedregs_num += (FLT_SAV_CNT - rd->savfltreguse);
113 parentargs_base = rd->memuse + savedregs_num;
115 #if defined(USE_THREADS) /* space to save argument of monitor_enter */
116 if (checksync && (m->flags & ACC_SYNCHRONIZED))
120 /* create method header */
122 (void) dseg_addaddress(cd, m); /* MethodPointer */
123 (void) dseg_adds4(cd, parentargs_base * 8); /* FrameSize */
125 #if defined(USE_THREADS)
126 /* IsSync contains the offset relative to the stack pointer for the
127 argument of monitor_exit used in the exception handler. Since the
128 offset could be zero and give a wrong meaning of the flag it is
132 if (checksync && (m->flags & ACC_SYNCHRONIZED))
133 (void) dseg_adds4(cd, (rd->memuse + 1) * 8); /* IsSync */
136 (void) dseg_adds4(cd, 0); /* IsSync */
138 (void) dseg_adds4(cd, m->isleafmethod); /* IsLeaf */
139 (void) dseg_adds4(cd, INT_SAV_CNT - rd->savintreguse); /* IntSave */
140 (void) dseg_adds4(cd, FLT_SAV_CNT - rd->savfltreguse); /* FltSave */
142 dseg_addlinenumbertablesize(cd);
144 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
146 /* create exception table */
148 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
149 dseg_addtarget(cd, ex->start);
150 dseg_addtarget(cd, ex->end);
151 dseg_addtarget(cd, ex->handler);
152 (void) dseg_addaddress(cd, ex->catchtype.cls);
155 /* initialize mcode variables */
157 mcodeptr = (s4 *) cd->mcodeptr;
159 MCODECHECK(128 + m->paramcount);
161 /* create stack frame (if necessary) */
163 if (parentargs_base) {
164 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
167 /* save return address and used callee saved registers */
170 if (!m->isleafmethod) {
171 p--; M_AST(REG_RA, REG_SP, p * 8);
173 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
174 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
176 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
177 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
180 /* take arguments out of register or stack frame */
184 for (p = 0, l = 0; p < md->paramcount; p++) {
185 t = md->paramtypes[p].type;
186 var = &(rd->locals[l][t]);
188 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
192 s1 = md->params[p].regoff;
193 if (IS_INT_LNG_TYPE(t)) { /* integer args */
194 if (!md->params[p].inmemory) { /* register arguments */
195 s2 = rd->argintregs[s1];
196 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
197 M_INTMOVE(s2, var->regoff);
199 } else { /* reg arg -> spilled */
200 M_LST(s2, REG_SP, var->regoff * 8);
203 } else { /* stack arguments */
204 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
205 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
207 } else { /* stack arg -> spilled */
208 var->regoff = parentargs_base + s1;
212 } else { /* floating args */
213 if (!md->params[p].inmemory) { /* register arguments */
214 s2 = rd->argfltregs[s1];
215 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
216 M_FLTMOVE(s2, var->regoff);
218 } else { /* reg arg -> spilled */
219 M_DST(s2, REG_SP, var->regoff * 8);
222 } else { /* stack arguments */
223 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
224 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
226 } else { /* stack-arg -> spilled */
227 var->regoff = parentargs_base + s1;
233 /* call monitorenter function */
235 #if defined(USE_THREADS)
236 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
237 /* stack offset for monitor argument */
242 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
244 for (p = 0; p < INT_ARG_CNT; p++)
245 M_LST(rd->argintregs[p], REG_SP, p * 8);
247 for (p = 0; p < FLT_ARG_CNT; p++)
248 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
250 s1 += INT_ARG_CNT + FLT_ARG_CNT;
253 /* decide which monitor enter function to call */
255 if (m->flags & ACC_STATIC) {
256 disp = dseg_addaddress(cd, m->class);
257 M_ALD(rd->argintregs[0], REG_PV, disp);
258 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
259 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
260 M_ALD(REG_PV, REG_PV, disp);
261 M_JSR(REG_RA, REG_PV);
262 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
263 M_LDA(REG_PV, REG_RA, disp);
266 M_BEQZ(rd->argintregs[0], 0);
267 codegen_addxnullrefs(cd, mcodeptr);
268 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
269 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
270 M_ALD(REG_PV, REG_PV, disp);
271 M_JSR(REG_RA, REG_PV);
272 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
273 M_LDA(REG_PV, REG_RA, disp);
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 disp = dseg_addaddress(cd, m);
320 M_ALD(REG_ITMP1, REG_PV, disp);
321 M_AST(REG_ITMP1, REG_SP, 0 * 8);
322 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
323 M_ALD(REG_PV, REG_PV, disp);
324 M_JSR(REG_RA, REG_PV);
325 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
326 M_LDA(REG_PV, REG_RA, disp);
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);
406 d = reg_of_var(rd, src, REG_IFTMP);
407 if ((src->varkind != STACKVAR)) {
409 if (IS_FLT_DBL_TYPE(s2)) {
410 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
411 s1 = rd->interfaces[len][s2].regoff;
414 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
416 store_reg_to_var_flt(src, d);
419 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
420 s1 = rd->interfaces[len][s2].regoff;
423 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
425 store_reg_to_var_int(src, d);
435 /* walk through all instructions */
440 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
441 if (iptr->line != currentline) {
442 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
443 currentline = iptr->line;
446 MCODECHECK(64); /* an instruction usually needs < 64 words */
449 case ICMD_INLINE_START:
450 case ICMD_INLINE_END:
453 case ICMD_NOP: /* ... ==> ... */
456 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
458 var_to_reg_int(s1, src, REG_ITMP1);
460 codegen_addxnullrefs(cd, mcodeptr);
463 /* constant operations ************************************************/
465 case ICMD_ICONST: /* ... ==> ..., constant */
466 /* op1 = 0, val.i = constant */
468 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
469 ICONST(d, iptr->val.i);
470 store_reg_to_var_int(iptr->dst, d);
473 case ICMD_LCONST: /* ... ==> ..., constant */
474 /* op1 = 0, val.l = constant */
476 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
477 LCONST(d, iptr->val.l);
478 store_reg_to_var_int(iptr->dst, d);
481 case ICMD_FCONST: /* ... ==> ..., constant */
482 /* op1 = 0, val.f = constant */
484 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
485 disp = dseg_addfloat(cd, iptr->val.f);
486 M_FLD(d, REG_PV, disp);
487 store_reg_to_var_flt(iptr->dst, d);
490 case ICMD_DCONST: /* ... ==> ..., constant */
491 /* op1 = 0, val.d = constant */
493 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
494 disp = dseg_adddouble(cd, iptr->val.d);
495 M_DLD(d, REG_PV, disp);
496 store_reg_to_var_flt(iptr->dst, d);
499 case ICMD_ACONST: /* ... ==> ..., constant */
500 /* op1 = 0, val.a = constant */
502 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
504 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
505 disp = dseg_addaddress(cd, iptr->val.a);
507 codegen_addpatchref(cd, mcodeptr,
509 (unresolved_class *) iptr->target, disp);
511 if (opt_showdisassemble)
514 M_ALD(d, REG_PV, disp);
517 if (iptr->val.a == NULL) {
518 M_INTMOVE(REG_ZERO, d);
520 disp = dseg_addaddress(cd, iptr->val.a);
521 M_ALD(d, REG_PV, disp);
524 store_reg_to_var_int(iptr->dst, d);
528 /* load/store operations **********************************************/
530 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
531 case ICMD_LLOAD: /* op1 = local variable */
534 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
535 if ((iptr->dst->varkind == LOCALVAR) &&
536 (iptr->dst->varnum == iptr->op1))
538 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
539 if (var->flags & INMEMORY) {
540 M_LLD(d, REG_SP, var->regoff * 8);
542 M_INTMOVE(var->regoff, d);
544 store_reg_to_var_int(iptr->dst, d);
547 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
548 case ICMD_DLOAD: /* op1 = local variable */
550 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
551 if ((iptr->dst->varkind == LOCALVAR) &&
552 (iptr->dst->varnum == iptr->op1))
554 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
555 if (var->flags & INMEMORY) {
556 M_DLD(d, REG_SP, var->regoff * 8);
558 M_FLTMOVE(var->regoff, d);
560 store_reg_to_var_flt(iptr->dst, d);
564 case ICMD_ISTORE: /* ..., value ==> ... */
565 case ICMD_LSTORE: /* op1 = local variable */
568 if ((src->varkind == LOCALVAR) &&
569 (src->varnum == iptr->op1))
571 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
572 if (var->flags & INMEMORY) {
573 var_to_reg_int(s1, src, REG_ITMP1);
574 M_LST(s1, REG_SP, var->regoff * 8);
576 var_to_reg_int(s1, src, var->regoff);
577 M_INTMOVE(s1, var->regoff);
581 case ICMD_FSTORE: /* ..., value ==> ... */
582 case ICMD_DSTORE: /* op1 = local variable */
584 if ((src->varkind == LOCALVAR) &&
585 (src->varnum == iptr->op1))
587 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
588 if (var->flags & INMEMORY) {
589 var_to_reg_flt(s1, src, REG_FTMP1);
590 M_DST(s1, REG_SP, var->regoff * 8);
592 var_to_reg_flt(s1, src, var->regoff);
593 M_FLTMOVE(s1, var->regoff);
598 /* pop/dup/swap operations ********************************************/
600 /* attention: double and longs are only one entry in CACAO ICMDs */
602 case ICMD_POP: /* ..., value ==> ... */
603 case ICMD_POP2: /* ..., value, value ==> ... */
606 case ICMD_DUP: /* ..., a ==> ..., a, a */
607 M_COPY(src, iptr->dst);
610 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
612 M_COPY(src, iptr->dst);
613 M_COPY(src->prev, iptr->dst->prev);
614 M_COPY(iptr->dst, iptr->dst->prev->prev);
617 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
619 M_COPY(src, iptr->dst);
620 M_COPY(src->prev, iptr->dst->prev);
621 M_COPY(src->prev->prev, iptr->dst->prev->prev);
622 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
625 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
627 M_COPY(src, iptr->dst);
628 M_COPY(src->prev, iptr->dst->prev);
631 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
633 M_COPY(src, iptr->dst);
634 M_COPY(src->prev, iptr->dst->prev);
635 M_COPY(src->prev->prev, iptr->dst->prev->prev);
636 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
637 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
640 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
642 M_COPY(src, iptr->dst);
643 M_COPY(src->prev, iptr->dst->prev);
644 M_COPY(src->prev->prev, iptr->dst->prev->prev);
645 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
646 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
647 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
650 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
652 M_COPY(src, iptr->dst->prev);
653 M_COPY(src->prev, iptr->dst);
657 /* integer operations *************************************************/
659 case ICMD_INEG: /* ..., value ==> ..., - value */
661 var_to_reg_int(s1, src, REG_ITMP1);
662 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
663 M_ISUB(REG_ZERO, s1, d);
664 store_reg_to_var_int(iptr->dst, d);
667 case ICMD_LNEG: /* ..., value ==> ..., - value */
669 var_to_reg_int(s1, src, REG_ITMP1);
670 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
671 M_LSUB(REG_ZERO, s1, d);
672 store_reg_to_var_int(iptr->dst, d);
675 case ICMD_I2L: /* ..., value ==> ..., value */
677 var_to_reg_int(s1, src, REG_ITMP1);
678 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
680 store_reg_to_var_int(iptr->dst, d);
683 case ICMD_L2I: /* ..., value ==> ..., value */
685 var_to_reg_int(s1, src, REG_ITMP1);
686 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
687 M_IADD(s1, REG_ZERO, d);
688 store_reg_to_var_int(iptr->dst, d);
691 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
693 var_to_reg_int(s1, src, REG_ITMP1);
694 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
695 if (has_ext_instr_set) {
698 M_SLL_IMM(s1, 56, d);
699 M_SRA_IMM( d, 56, d);
701 store_reg_to_var_int(iptr->dst, d);
704 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
706 var_to_reg_int(s1, src, REG_ITMP1);
707 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
709 store_reg_to_var_int(iptr->dst, d);
712 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
714 var_to_reg_int(s1, src, REG_ITMP1);
715 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
716 if (has_ext_instr_set) {
719 M_SLL_IMM(s1, 48, d);
720 M_SRA_IMM( d, 48, d);
722 store_reg_to_var_int(iptr->dst, d);
726 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
728 var_to_reg_int(s1, src->prev, REG_ITMP1);
729 var_to_reg_int(s2, src, REG_ITMP2);
730 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
732 store_reg_to_var_int(iptr->dst, d);
735 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
736 /* val.i = constant */
738 var_to_reg_int(s1, src, REG_ITMP1);
739 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
740 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
741 M_IADD_IMM(s1, iptr->val.i, d);
743 ICONST(REG_ITMP2, iptr->val.i);
744 M_IADD(s1, REG_ITMP2, d);
746 store_reg_to_var_int(iptr->dst, d);
749 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
751 var_to_reg_int(s1, src->prev, REG_ITMP1);
752 var_to_reg_int(s2, src, REG_ITMP2);
753 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
755 store_reg_to_var_int(iptr->dst, d);
758 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
759 /* val.l = constant */
761 var_to_reg_int(s1, src, REG_ITMP1);
762 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
763 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
764 M_LADD_IMM(s1, iptr->val.l, d);
766 LCONST(REG_ITMP2, iptr->val.l);
767 M_LADD(s1, REG_ITMP2, d);
769 store_reg_to_var_int(iptr->dst, d);
772 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
774 var_to_reg_int(s1, src->prev, REG_ITMP1);
775 var_to_reg_int(s2, src, REG_ITMP2);
776 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
778 store_reg_to_var_int(iptr->dst, d);
781 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
782 /* val.i = constant */
784 var_to_reg_int(s1, src, REG_ITMP1);
785 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
786 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
787 M_ISUB_IMM(s1, iptr->val.i, d);
789 ICONST(REG_ITMP2, iptr->val.i);
790 M_ISUB(s1, REG_ITMP2, d);
792 store_reg_to_var_int(iptr->dst, d);
795 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
797 var_to_reg_int(s1, src->prev, REG_ITMP1);
798 var_to_reg_int(s2, src, REG_ITMP2);
799 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
801 store_reg_to_var_int(iptr->dst, d);
804 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
805 /* val.l = constant */
807 var_to_reg_int(s1, src, REG_ITMP1);
808 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
809 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
810 M_LSUB_IMM(s1, iptr->val.l, d);
812 LCONST(REG_ITMP2, iptr->val.l);
813 M_LSUB(s1, REG_ITMP2, d);
815 store_reg_to_var_int(iptr->dst, d);
818 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
820 var_to_reg_int(s1, src->prev, REG_ITMP1);
821 var_to_reg_int(s2, src, REG_ITMP2);
822 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
824 store_reg_to_var_int(iptr->dst, d);
827 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
828 /* val.i = constant */
830 var_to_reg_int(s1, src, REG_ITMP1);
831 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
832 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
833 M_IMUL_IMM(s1, iptr->val.i, d);
835 ICONST(REG_ITMP2, iptr->val.i);
836 M_IMUL(s1, REG_ITMP2, d);
838 store_reg_to_var_int(iptr->dst, d);
841 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
843 var_to_reg_int(s1, src->prev, REG_ITMP1);
844 var_to_reg_int(s2, src, REG_ITMP2);
845 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
847 store_reg_to_var_int(iptr->dst, d);
850 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
851 /* val.l = constant */
853 var_to_reg_int(s1, src, REG_ITMP1);
854 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
855 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
856 M_LMUL_IMM(s1, iptr->val.l, d);
858 LCONST(REG_ITMP2, iptr->val.l);
859 M_LMUL(s1, REG_ITMP2, d);
861 store_reg_to_var_int(iptr->dst, d);
864 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
865 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
867 var_to_reg_int(s1, src->prev, REG_ITMP1);
868 var_to_reg_int(s2, src, REG_ITMP2);
869 d = reg_of_var(rd, iptr->dst, REG_RESULT);
871 codegen_addxdivrefs(cd, mcodeptr);
873 M_MOV(s1, rd->argintregs[0]);
874 M_MOV(s2, rd->argintregs[1]);
876 disp = dseg_addaddress(cd, bte->fp);
877 M_ALD(REG_PV, REG_PV, disp);
878 M_JSR(REG_RA, REG_PV);
879 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
880 M_LDA(REG_PV, REG_RA, -disp);
882 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
883 store_reg_to_var_int(iptr->dst, d);
886 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
887 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
889 var_to_reg_int(s1, src->prev, REG_ITMP1);
890 var_to_reg_int(s2, src, REG_ITMP2);
891 d = reg_of_var(rd, iptr->dst, REG_RESULT);
893 codegen_addxdivrefs(cd, mcodeptr);
895 M_MOV(s1, rd->argintregs[0]);
896 M_MOV(s2, rd->argintregs[1]);
898 disp = dseg_addaddress(cd, bte->fp);
899 M_ALD(REG_PV, REG_PV, disp);
900 M_JSR(REG_RA, REG_PV);
901 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
902 M_LDA(REG_PV, REG_RA, -disp);
904 M_INTMOVE(REG_RESULT, d);
905 store_reg_to_var_int(iptr->dst, d);
908 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
909 case ICMD_LDIVPOW2: /* val.i = constant */
911 var_to_reg_int(s1, src, REG_ITMP1);
912 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
913 if (iptr->val.i <= 15) {
914 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
915 M_CMOVGE(s1, s1, REG_ITMP2);
917 M_SRA_IMM(s1, 63, REG_ITMP2);
918 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
919 M_LADD(s1, REG_ITMP2, REG_ITMP2);
921 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
922 store_reg_to_var_int(iptr->dst, d);
925 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
927 var_to_reg_int(s1, src->prev, REG_ITMP1);
928 var_to_reg_int(s2, src, REG_ITMP2);
929 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
930 M_AND_IMM(s2, 0x1f, REG_ITMP3);
931 M_SLL(s1, REG_ITMP3, d);
932 M_IADD(d, REG_ZERO, d);
933 store_reg_to_var_int(iptr->dst, d);
936 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
937 /* val.i = constant */
939 var_to_reg_int(s1, src, REG_ITMP1);
940 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
941 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
942 M_IADD(d, REG_ZERO, d);
943 store_reg_to_var_int(iptr->dst, d);
946 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
948 var_to_reg_int(s1, src->prev, REG_ITMP1);
949 var_to_reg_int(s2, src, REG_ITMP2);
950 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
951 M_AND_IMM(s2, 0x1f, REG_ITMP3);
952 M_SRA(s1, REG_ITMP3, d);
953 store_reg_to_var_int(iptr->dst, d);
956 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
957 /* val.i = constant */
959 var_to_reg_int(s1, src, REG_ITMP1);
960 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
961 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
962 store_reg_to_var_int(iptr->dst, d);
965 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
967 var_to_reg_int(s1, src->prev, REG_ITMP1);
968 var_to_reg_int(s2, src, REG_ITMP2);
969 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
970 M_AND_IMM(s2, 0x1f, REG_ITMP2);
972 M_SRL(d, REG_ITMP2, d);
973 M_IADD(d, REG_ZERO, d);
974 store_reg_to_var_int(iptr->dst, d);
977 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
978 /* val.i = constant */
980 var_to_reg_int(s1, src, REG_ITMP1);
981 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
983 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
984 M_IADD(d, REG_ZERO, d);
985 store_reg_to_var_int(iptr->dst, d);
988 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
990 var_to_reg_int(s1, src->prev, REG_ITMP1);
991 var_to_reg_int(s2, src, REG_ITMP2);
992 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
994 store_reg_to_var_int(iptr->dst, d);
997 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
998 /* val.i = constant */
1000 var_to_reg_int(s1, src, REG_ITMP1);
1001 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1002 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1003 store_reg_to_var_int(iptr->dst, d);
1006 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1008 var_to_reg_int(s1, src->prev, REG_ITMP1);
1009 var_to_reg_int(s2, src, REG_ITMP2);
1010 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1012 store_reg_to_var_int(iptr->dst, d);
1015 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1016 /* val.i = constant */
1018 var_to_reg_int(s1, src, REG_ITMP1);
1019 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1020 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1021 store_reg_to_var_int(iptr->dst, d);
1024 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1026 var_to_reg_int(s1, src->prev, REG_ITMP1);
1027 var_to_reg_int(s2, src, REG_ITMP2);
1028 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1030 store_reg_to_var_int(iptr->dst, d);
1033 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1034 /* val.i = constant */
1036 var_to_reg_int(s1, src, REG_ITMP1);
1037 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1038 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1039 store_reg_to_var_int(iptr->dst, d);
1042 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1045 var_to_reg_int(s1, src->prev, REG_ITMP1);
1046 var_to_reg_int(s2, src, REG_ITMP2);
1047 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1049 store_reg_to_var_int(iptr->dst, d);
1052 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1053 /* val.i = constant */
1055 var_to_reg_int(s1, src, REG_ITMP1);
1056 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1057 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1058 M_AND_IMM(s1, iptr->val.i, d);
1059 } else if (iptr->val.i == 0xffff) {
1061 } else if (iptr->val.i == 0xffffff) {
1062 M_ZAPNOT_IMM(s1, 0x07, d);
1064 ICONST(REG_ITMP2, iptr->val.i);
1065 M_AND(s1, REG_ITMP2, d);
1067 store_reg_to_var_int(iptr->dst, d);
1070 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1071 /* val.i = constant */
1073 var_to_reg_int(s1, src, REG_ITMP1);
1074 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1076 M_MOV(s1, REG_ITMP1);
1079 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1080 M_AND_IMM(s1, iptr->val.i, d);
1082 M_ISUB(REG_ZERO, s1, d);
1083 M_AND_IMM(d, iptr->val.i, d);
1084 } else if (iptr->val.i == 0xffff) {
1087 M_ISUB(REG_ZERO, s1, d);
1089 } else if (iptr->val.i == 0xffffff) {
1090 M_ZAPNOT_IMM(s1, 0x07, d);
1092 M_ISUB(REG_ZERO, s1, d);
1093 M_ZAPNOT_IMM(d, 0x07, d);
1095 ICONST(REG_ITMP2, iptr->val.i);
1096 M_AND(s1, REG_ITMP2, d);
1098 M_ISUB(REG_ZERO, s1, d);
1099 M_AND(d, REG_ITMP2, d);
1101 M_ISUB(REG_ZERO, d, d);
1102 store_reg_to_var_int(iptr->dst, d);
1105 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1106 /* val.l = constant */
1108 var_to_reg_int(s1, src, REG_ITMP1);
1109 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1110 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1111 M_AND_IMM(s1, iptr->val.l, d);
1112 } else if (iptr->val.l == 0xffffL) {
1114 } else if (iptr->val.l == 0xffffffL) {
1115 M_ZAPNOT_IMM(s1, 0x07, d);
1116 } else if (iptr->val.l == 0xffffffffL) {
1118 } else if (iptr->val.l == 0xffffffffffL) {
1119 M_ZAPNOT_IMM(s1, 0x1f, d);
1120 } else if (iptr->val.l == 0xffffffffffffL) {
1121 M_ZAPNOT_IMM(s1, 0x3f, d);
1122 } else if (iptr->val.l == 0xffffffffffffffL) {
1123 M_ZAPNOT_IMM(s1, 0x7f, d);
1125 LCONST(REG_ITMP2, iptr->val.l);
1126 M_AND(s1, REG_ITMP2, d);
1128 store_reg_to_var_int(iptr->dst, d);
1131 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1132 /* val.l = constant */
1134 var_to_reg_int(s1, src, REG_ITMP1);
1135 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1137 M_MOV(s1, REG_ITMP1);
1140 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1141 M_AND_IMM(s1, iptr->val.l, d);
1143 M_LSUB(REG_ZERO, s1, d);
1144 M_AND_IMM(d, iptr->val.l, d);
1145 } else if (iptr->val.l == 0xffffL) {
1148 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);
1155 } else if (iptr->val.l == 0xffffffffL) {
1158 M_LSUB(REG_ZERO, s1, d);
1160 } else if (iptr->val.l == 0xffffffffffL) {
1161 M_ZAPNOT_IMM(s1, 0x1f, d);
1163 M_LSUB(REG_ZERO, s1, d);
1164 M_ZAPNOT_IMM(d, 0x1f, d);
1165 } else if (iptr->val.l == 0xffffffffffffL) {
1166 M_ZAPNOT_IMM(s1, 0x3f, d);
1168 M_LSUB(REG_ZERO, s1, d);
1169 M_ZAPNOT_IMM(d, 0x3f, d);
1170 } else if (iptr->val.l == 0xffffffffffffffL) {
1171 M_ZAPNOT_IMM(s1, 0x7f, d);
1173 M_LSUB(REG_ZERO, s1, d);
1174 M_ZAPNOT_IMM(d, 0x7f, d);
1176 LCONST(REG_ITMP2, iptr->val.l);
1177 M_AND(s1, REG_ITMP2, d);
1179 M_LSUB(REG_ZERO, s1, d);
1180 M_AND(d, REG_ITMP2, d);
1182 M_LSUB(REG_ZERO, d, d);
1183 store_reg_to_var_int(iptr->dst, d);
1186 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1189 var_to_reg_int(s1, src->prev, REG_ITMP1);
1190 var_to_reg_int(s2, src, REG_ITMP2);
1191 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1193 store_reg_to_var_int(iptr->dst, d);
1196 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1197 /* val.i = constant */
1199 var_to_reg_int(s1, src, REG_ITMP1);
1200 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1201 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1202 M_OR_IMM(s1, iptr->val.i, d);
1204 ICONST(REG_ITMP2, iptr->val.i);
1205 M_OR(s1, REG_ITMP2, d);
1207 store_reg_to_var_int(iptr->dst, d);
1210 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1211 /* val.l = constant */
1213 var_to_reg_int(s1, src, REG_ITMP1);
1214 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1215 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1216 M_OR_IMM(s1, iptr->val.l, d);
1218 LCONST(REG_ITMP2, iptr->val.l);
1219 M_OR(s1, REG_ITMP2, d);
1221 store_reg_to_var_int(iptr->dst, d);
1224 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1227 var_to_reg_int(s1, src->prev, REG_ITMP1);
1228 var_to_reg_int(s2, src, REG_ITMP2);
1229 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1231 store_reg_to_var_int(iptr->dst, d);
1234 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1235 /* val.i = constant */
1237 var_to_reg_int(s1, src, REG_ITMP1);
1238 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1239 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1240 M_XOR_IMM(s1, iptr->val.i, d);
1242 ICONST(REG_ITMP2, iptr->val.i);
1243 M_XOR(s1, REG_ITMP2, d);
1245 store_reg_to_var_int(iptr->dst, d);
1248 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1249 /* val.l = constant */
1251 var_to_reg_int(s1, src, REG_ITMP1);
1252 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1253 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1254 M_XOR_IMM(s1, iptr->val.l, d);
1256 LCONST(REG_ITMP2, iptr->val.l);
1257 M_XOR(s1, REG_ITMP2, d);
1259 store_reg_to_var_int(iptr->dst, d);
1263 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1265 var_to_reg_int(s1, src->prev, REG_ITMP1);
1266 var_to_reg_int(s2, src, REG_ITMP2);
1267 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1268 M_CMPLT(s1, s2, REG_ITMP3);
1269 M_CMPLT(s2, s1, REG_ITMP1);
1270 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1271 store_reg_to_var_int(iptr->dst, d);
1275 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1276 /* op1 = variable, val.i = constant */
1278 var = &(rd->locals[iptr->op1][TYPE_INT]);
1279 if (var->flags & INMEMORY) {
1281 M_LLD(s1, REG_SP, var->regoff * 8);
1284 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1285 M_IADD_IMM(s1, iptr->val.i, s1);
1286 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1287 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1289 M_LDA (s1, s1, iptr->val.i);
1290 M_IADD(s1, REG_ZERO, s1);
1292 if (var->flags & INMEMORY)
1293 M_LST(s1, REG_SP, var->regoff * 8);
1297 /* floating operations ************************************************/
1299 case ICMD_FNEG: /* ..., value ==> ..., - value */
1301 var_to_reg_flt(s1, src, REG_FTMP1);
1302 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1304 store_reg_to_var_flt(iptr->dst, d);
1307 case ICMD_DNEG: /* ..., value ==> ..., - value */
1309 var_to_reg_flt(s1, src, REG_FTMP1);
1310 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1312 store_reg_to_var_flt(iptr->dst, d);
1315 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1317 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1318 var_to_reg_flt(s2, src, REG_FTMP2);
1319 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1323 if (d == s1 || d == s2) {
1324 M_FADDS(s1, s2, REG_FTMP3);
1326 M_FMOV(REG_FTMP3, d);
1332 store_reg_to_var_flt(iptr->dst, d);
1335 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1337 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1338 var_to_reg_flt(s2, src, REG_FTMP2);
1339 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1343 if (d == s1 || d == s2) {
1344 M_DADDS(s1, s2, REG_FTMP3);
1346 M_FMOV(REG_FTMP3, d);
1352 store_reg_to_var_flt(iptr->dst, d);
1355 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1357 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1358 var_to_reg_flt(s2, src, REG_FTMP2);
1359 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1363 if (d == s1 || d == s2) {
1364 M_FSUBS(s1, s2, REG_FTMP3);
1366 M_FMOV(REG_FTMP3, d);
1372 store_reg_to_var_flt(iptr->dst, d);
1375 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1377 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1378 var_to_reg_flt(s2, src, REG_FTMP2);
1379 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1383 if (d == s1 || d == s2) {
1384 M_DSUBS(s1, s2, REG_FTMP3);
1386 M_FMOV(REG_FTMP3, d);
1392 store_reg_to_var_flt(iptr->dst, d);
1395 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1397 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1398 var_to_reg_flt(s2, src, REG_FTMP2);
1399 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1403 if (d == s1 || d == s2) {
1404 M_FMULS(s1, s2, REG_FTMP3);
1406 M_FMOV(REG_FTMP3, d);
1412 store_reg_to_var_flt(iptr->dst, d);
1415 case ICMD_DMUL: /* ..., 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);
1423 if (d == s1 || d == s2) {
1424 M_DMULS(s1, s2, REG_FTMP3);
1426 M_FMOV(REG_FTMP3, d);
1432 store_reg_to_var_flt(iptr->dst, d);
1435 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1437 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1438 var_to_reg_flt(s2, src, REG_FTMP2);
1439 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1443 if (d == s1 || d == s2) {
1444 M_FDIVS(s1, s2, REG_FTMP3);
1446 M_FMOV(REG_FTMP3, d);
1452 store_reg_to_var_flt(iptr->dst, d);
1455 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1457 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1458 var_to_reg_flt(s2, src, REG_FTMP2);
1459 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1463 if (d == s1 || d == s2) {
1464 M_DDIVS(s1, s2, REG_FTMP3);
1466 M_FMOV(REG_FTMP3, d);
1472 store_reg_to_var_flt(iptr->dst, d);
1475 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1477 var_to_reg_int(s1, src, REG_ITMP1);
1478 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1479 disp = dseg_adddouble(cd, 0.0);
1480 M_LST(s1, REG_PV, disp);
1481 M_DLD(d, REG_PV, disp);
1483 store_reg_to_var_flt(iptr->dst, d);
1486 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1488 var_to_reg_int(s1, src, REG_ITMP1);
1489 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1490 disp = dseg_adddouble(cd, 0.0);
1491 M_LST(s1, REG_PV, disp);
1492 M_DLD(d, REG_PV, disp);
1494 store_reg_to_var_flt(iptr->dst, d);
1497 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1499 var_to_reg_flt(s1, src, REG_FTMP1);
1500 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1501 disp = dseg_adddouble(cd, 0.0);
1502 M_CVTDL_C(s1, REG_FTMP2);
1503 M_CVTLI(REG_FTMP2, REG_FTMP3);
1504 M_DST(REG_FTMP3, REG_PV, disp);
1505 M_ILD(d, REG_PV, disp);
1506 store_reg_to_var_int(iptr->dst, d);
1509 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1511 var_to_reg_flt(s1, src, REG_FTMP1);
1512 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1513 disp = dseg_adddouble(cd, 0.0);
1514 M_CVTDL_C(s1, REG_FTMP2);
1515 M_DST(REG_FTMP2, REG_PV, disp);
1516 M_LLD(d, REG_PV, disp);
1517 store_reg_to_var_int(iptr->dst, d);
1520 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1522 var_to_reg_flt(s1, src, REG_FTMP1);
1523 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1526 store_reg_to_var_flt(iptr->dst, d);
1529 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1531 var_to_reg_flt(s1, src, REG_FTMP1);
1532 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1539 store_reg_to_var_flt(iptr->dst, d);
1542 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1544 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1545 var_to_reg_flt(s2, src, REG_FTMP2);
1546 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1548 M_LSUB_IMM(REG_ZERO, 1, d);
1549 M_FCMPEQ(s1, s2, REG_FTMP3);
1550 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1552 M_FCMPLT(s2, s1, REG_FTMP3);
1553 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1554 M_LADD_IMM(REG_ZERO, 1, d);
1556 M_LSUB_IMM(REG_ZERO, 1, d);
1557 M_FCMPEQS(s1, s2, REG_FTMP3);
1559 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1561 M_FCMPLTS(s2, s1, REG_FTMP3);
1563 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1564 M_LADD_IMM(REG_ZERO, 1, d);
1566 store_reg_to_var_int(iptr->dst, d);
1569 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1571 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1572 var_to_reg_flt(s2, src, REG_FTMP2);
1573 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1575 M_LADD_IMM(REG_ZERO, 1, d);
1576 M_FCMPEQ(s1, s2, REG_FTMP3);
1577 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1579 M_FCMPLT(s1, s2, REG_FTMP3);
1580 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1581 M_LSUB_IMM(REG_ZERO, 1, d);
1583 M_LADD_IMM(REG_ZERO, 1, d);
1584 M_FCMPEQS(s1, s2, REG_FTMP3);
1586 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1588 M_FCMPLTS(s1, s2, REG_FTMP3);
1590 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1591 M_LSUB_IMM(REG_ZERO, 1, d);
1593 store_reg_to_var_int(iptr->dst, d);
1597 /* memory operations **************************************************/
1599 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1601 var_to_reg_int(s1, src, REG_ITMP1);
1602 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1603 gen_nullptr_check(s1);
1604 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1605 store_reg_to_var_int(iptr->dst, d);
1608 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1610 var_to_reg_int(s1, src->prev, REG_ITMP1);
1611 var_to_reg_int(s2, src, REG_ITMP2);
1612 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1613 if (iptr->op1 == 0) {
1614 gen_nullptr_check(s1);
1617 if (has_ext_instr_set) {
1618 M_LADD (s2, s1, REG_ITMP1);
1619 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1622 M_LADD(s2, s1, REG_ITMP1);
1623 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1624 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1625 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1626 M_SRA_IMM(d, 56, d);
1628 store_reg_to_var_int(iptr->dst, d);
1631 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1633 var_to_reg_int(s1, src->prev, REG_ITMP1);
1634 var_to_reg_int(s2, src, REG_ITMP2);
1635 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1636 if (iptr->op1 == 0) {
1637 gen_nullptr_check(s1);
1640 if (has_ext_instr_set) {
1641 M_LADD(s2, s1, REG_ITMP1);
1642 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1643 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1645 M_LADD (s2, s1, REG_ITMP1);
1646 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1647 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1648 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1649 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1651 store_reg_to_var_int(iptr->dst, d);
1654 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1656 var_to_reg_int(s1, src->prev, REG_ITMP1);
1657 var_to_reg_int(s2, src, REG_ITMP2);
1658 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1659 if (iptr->op1 == 0) {
1660 gen_nullptr_check(s1);
1663 if (has_ext_instr_set) {
1664 M_LADD(s2, s1, REG_ITMP1);
1665 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1666 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1669 M_LADD(s2, s1, REG_ITMP1);
1670 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1671 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1672 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1673 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1674 M_SRA_IMM(d, 48, d);
1676 store_reg_to_var_int(iptr->dst, d);
1679 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1681 var_to_reg_int(s1, src->prev, REG_ITMP1);
1682 var_to_reg_int(s2, src, REG_ITMP2);
1683 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1684 if (iptr->op1 == 0) {
1685 gen_nullptr_check(s1);
1688 M_S4ADDQ(s2, s1, REG_ITMP1);
1689 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1690 store_reg_to_var_int(iptr->dst, d);
1693 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1695 var_to_reg_int(s1, src->prev, REG_ITMP1);
1696 var_to_reg_int(s2, src, REG_ITMP2);
1697 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1698 if (iptr->op1 == 0) {
1699 gen_nullptr_check(s1);
1702 M_S8ADDQ(s2, s1, REG_ITMP1);
1703 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1704 store_reg_to_var_int(iptr->dst, d);
1707 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1709 var_to_reg_int(s1, src->prev, REG_ITMP1);
1710 var_to_reg_int(s2, src, REG_ITMP2);
1711 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1712 if (iptr->op1 == 0) {
1713 gen_nullptr_check(s1);
1716 M_S4ADDQ(s2, s1, REG_ITMP1);
1717 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1718 store_reg_to_var_flt(iptr->dst, d);
1721 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1723 var_to_reg_int(s1, src->prev, REG_ITMP1);
1724 var_to_reg_int(s2, src, REG_ITMP2);
1725 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1726 if (iptr->op1 == 0) {
1727 gen_nullptr_check(s1);
1730 M_S8ADDQ(s2, s1, REG_ITMP1);
1731 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1732 store_reg_to_var_flt(iptr->dst, d);
1735 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1737 var_to_reg_int(s1, src->prev, REG_ITMP1);
1738 var_to_reg_int(s2, src, REG_ITMP2);
1739 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1740 if (iptr->op1 == 0) {
1741 gen_nullptr_check(s1);
1744 M_SAADDQ(s2, s1, REG_ITMP1);
1745 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1746 store_reg_to_var_int(iptr->dst, d);
1750 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1752 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1753 var_to_reg_int(s2, src->prev, REG_ITMP2);
1754 if (iptr->op1 == 0) {
1755 gen_nullptr_check(s1);
1758 var_to_reg_int(s3, src, REG_ITMP3);
1759 if (has_ext_instr_set) {
1760 M_LADD(s2, s1, REG_ITMP1);
1761 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1763 M_LADD(s2, s1, REG_ITMP1);
1764 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1765 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1766 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1767 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1768 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1769 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1773 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1775 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1776 var_to_reg_int(s2, src->prev, REG_ITMP2);
1777 if (iptr->op1 == 0) {
1778 gen_nullptr_check(s1);
1781 var_to_reg_int(s3, src, REG_ITMP3);
1782 if (has_ext_instr_set) {
1783 M_LADD(s2, s1, REG_ITMP1);
1784 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1785 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1787 M_LADD(s2, s1, REG_ITMP1);
1788 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1789 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1790 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1791 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1792 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1793 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1794 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1798 case ICMD_SASTORE: /* ..., 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 if (has_ext_instr_set) {
1808 M_LADD(s2, s1, REG_ITMP1);
1809 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1810 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1812 M_LADD(s2, s1, REG_ITMP1);
1813 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1814 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1815 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1816 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1817 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1818 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1819 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1823 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1825 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1826 var_to_reg_int(s2, src->prev, REG_ITMP2);
1827 if (iptr->op1 == 0) {
1828 gen_nullptr_check(s1);
1831 var_to_reg_int(s3, src, REG_ITMP3);
1832 M_S4ADDQ(s2, s1, REG_ITMP1);
1833 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1836 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1838 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1839 var_to_reg_int(s2, src->prev, REG_ITMP2);
1840 if (iptr->op1 == 0) {
1841 gen_nullptr_check(s1);
1844 var_to_reg_int(s3, src, REG_ITMP3);
1845 M_S8ADDQ(s2, s1, REG_ITMP1);
1846 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1849 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1851 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1852 var_to_reg_int(s2, src->prev, REG_ITMP2);
1853 if (iptr->op1 == 0) {
1854 gen_nullptr_check(s1);
1857 var_to_reg_flt(s3, src, REG_FTMP3);
1858 M_S4ADDQ(s2, s1, REG_ITMP1);
1859 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1862 case ICMD_DASTORE: /* ..., 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_flt(s3, src, REG_FTMP3);
1871 M_S8ADDQ(s2, s1, REG_ITMP1);
1872 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1875 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1877 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1878 var_to_reg_int(s2, src->prev, REG_ITMP2);
1879 if (iptr->op1 == 0) {
1880 gen_nullptr_check(s1);
1883 var_to_reg_int(s3, src, REG_ITMP3);
1885 M_MOV(s1, rd->argintregs[0]);
1886 M_MOV(s3, rd->argintregs[1]);
1887 disp = dseg_addaddress(cd, BUILTIN_canstore);
1888 M_ALD(REG_PV, REG_PV, disp);
1889 M_JSR(REG_RA, REG_PV);
1890 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1891 M_LDA(REG_PV, REG_RA, -disp);
1893 M_BEQZ(REG_RESULT, 0);
1894 codegen_addxstorerefs(cd, mcodeptr);
1896 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1897 var_to_reg_int(s2, src->prev, REG_ITMP2);
1898 var_to_reg_int(s3, src, REG_ITMP3);
1899 M_SAADDQ(s2, s1, REG_ITMP1);
1900 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1904 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1906 var_to_reg_int(s1, src->prev, REG_ITMP1);
1907 var_to_reg_int(s2, src, REG_ITMP2);
1908 if (iptr->op1 == 0) {
1909 gen_nullptr_check(s1);
1912 M_S4ADDQ(s2, s1, REG_ITMP1);
1913 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1916 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1918 var_to_reg_int(s1, src->prev, REG_ITMP1);
1919 var_to_reg_int(s2, src, REG_ITMP2);
1920 if (iptr->op1 == 0) {
1921 gen_nullptr_check(s1);
1924 M_S8ADDQ(s2, s1, REG_ITMP1);
1925 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1928 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1930 var_to_reg_int(s1, src->prev, REG_ITMP1);
1931 var_to_reg_int(s2, src, REG_ITMP2);
1932 if (iptr->op1 == 0) {
1933 gen_nullptr_check(s1);
1936 M_SAADDQ(s2, s1, REG_ITMP1);
1937 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1940 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1942 var_to_reg_int(s1, src->prev, REG_ITMP1);
1943 var_to_reg_int(s2, src, REG_ITMP2);
1944 if (iptr->op1 == 0) {
1945 gen_nullptr_check(s1);
1948 if (has_ext_instr_set) {
1949 M_LADD(s2, s1, REG_ITMP1);
1950 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1953 M_LADD(s2, s1, REG_ITMP1);
1954 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1955 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1956 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1957 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1958 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1959 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1963 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1965 var_to_reg_int(s1, src->prev, REG_ITMP1);
1966 var_to_reg_int(s2, src, REG_ITMP2);
1967 if (iptr->op1 == 0) {
1968 gen_nullptr_check(s1);
1971 if (has_ext_instr_set) {
1972 M_LADD(s2, s1, REG_ITMP1);
1973 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1974 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1977 M_LADD(s2, s1, REG_ITMP1);
1978 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1979 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1980 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1981 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1982 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1983 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1984 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1988 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1990 var_to_reg_int(s1, src->prev, REG_ITMP1);
1991 var_to_reg_int(s2, src, REG_ITMP2);
1992 if (iptr->op1 == 0) {
1993 gen_nullptr_check(s1);
1996 if (has_ext_instr_set) {
1997 M_LADD(s2, s1, REG_ITMP1);
1998 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1999 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2002 M_LADD(s2, s1, REG_ITMP1);
2003 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2004 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2005 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2006 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2007 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2008 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2009 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2014 case ICMD_GETSTATIC: /* ... ==> ..., value */
2015 /* op1 = type, val.a = field address */
2018 disp = dseg_addaddress(cd, 0);
2020 codegen_addpatchref(cd, mcodeptr,
2021 PATCHER_get_putstatic,
2022 (unresolved_field *) iptr->target, disp);
2024 if (opt_showdisassemble)
2029 fieldinfo *fi = iptr->val.a;
2031 disp = dseg_addaddress(cd, &(fi->value));
2033 if (!(fi->class->state & CLASS_INITIALIZED)) {
2034 codegen_addpatchref(cd, mcodeptr,
2035 PATCHER_clinit, fi->class, 0);
2037 if (opt_showdisassemble)
2042 M_ALD(REG_ITMP1, REG_PV, disp);
2043 switch (iptr->op1) {
2045 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2046 M_ILD(d, REG_ITMP1, 0);
2047 store_reg_to_var_int(iptr->dst, d);
2050 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2051 M_LLD(d, REG_ITMP1, 0);
2052 store_reg_to_var_int(iptr->dst, d);
2055 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2056 M_ALD(d, REG_ITMP1, 0);
2057 store_reg_to_var_int(iptr->dst, d);
2060 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2061 M_FLD(d, REG_ITMP1, 0);
2062 store_reg_to_var_flt(iptr->dst, d);
2065 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2066 M_DLD(d, REG_ITMP1, 0);
2067 store_reg_to_var_flt(iptr->dst, d);
2072 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2073 /* op1 = type, val.a = field address */
2076 disp = dseg_addaddress(cd, 0);
2078 codegen_addpatchref(cd, mcodeptr,
2079 PATCHER_get_putstatic,
2080 (unresolved_field *) iptr->target, disp);
2082 if (opt_showdisassemble)
2086 fieldinfo *fi = iptr->val.a;
2088 disp = dseg_addaddress(cd, &(fi->value));
2090 if (!(fi->class->state & CLASS_INITIALIZED)) {
2091 codegen_addpatchref(cd, mcodeptr,
2092 PATCHER_clinit, fi->class, 0);
2094 if (opt_showdisassemble)
2099 M_ALD(REG_ITMP1, REG_PV, disp);
2100 switch (iptr->op1) {
2102 var_to_reg_int(s2, src, REG_ITMP2);
2103 M_IST(s2, REG_ITMP1, 0);
2106 var_to_reg_int(s2, src, REG_ITMP2);
2107 M_LST(s2, REG_ITMP1, 0);
2110 var_to_reg_int(s2, src, REG_ITMP2);
2111 M_AST(s2, REG_ITMP1, 0);
2114 var_to_reg_flt(s2, src, REG_FTMP2);
2115 M_FST(s2, REG_ITMP1, 0);
2118 var_to_reg_flt(s2, src, REG_FTMP2);
2119 M_DST(s2, REG_ITMP1, 0);
2124 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2125 /* val = value (in current instruction) */
2126 /* op1 = type, val.a = field address (in */
2127 /* following NOP) */
2129 if (!iptr[1].val.a) {
2130 disp = dseg_addaddress(cd, 0);
2132 codegen_addpatchref(cd, mcodeptr,
2133 PATCHER_get_putstatic,
2134 (unresolved_field *) iptr[1].target, disp);
2136 if (opt_showdisassemble)
2140 fieldinfo *fi = iptr[1].val.a;
2142 disp = dseg_addaddress(cd, &(fi->value));
2144 if (!(fi->class->state & CLASS_INITIALIZED)) {
2145 codegen_addpatchref(cd, mcodeptr,
2146 PATCHER_clinit, fi->class, 0);
2148 if (opt_showdisassemble)
2153 M_ALD(REG_ITMP1, REG_PV, disp);
2154 switch (iptr->op1) {
2156 M_IST(REG_ZERO, REG_ITMP1, 0);
2159 M_LST(REG_ZERO, REG_ITMP1, 0);
2162 M_AST(REG_ZERO, REG_ITMP1, 0);
2165 M_FST(REG_ZERO, REG_ITMP1, 0);
2168 M_DST(REG_ZERO, REG_ITMP1, 0);
2174 case ICMD_GETFIELD: /* ... ==> ..., value */
2175 /* op1 = type, val.i = field offset */
2177 var_to_reg_int(s1, src, REG_ITMP1);
2178 gen_nullptr_check(s1);
2181 codegen_addpatchref(cd, mcodeptr,
2182 PATCHER_get_putfield,
2183 (unresolved_field *) iptr->target, 0);
2185 if (opt_showdisassemble)
2191 disp = ((fieldinfo *) (iptr->val.a))->offset;
2194 switch (iptr->op1) {
2196 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2198 store_reg_to_var_int(iptr->dst, d);
2201 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2203 store_reg_to_var_int(iptr->dst, d);
2206 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2208 store_reg_to_var_int(iptr->dst, d);
2211 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2213 store_reg_to_var_flt(iptr->dst, d);
2216 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2218 store_reg_to_var_flt(iptr->dst, d);
2223 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2224 /* op1 = type, val.a = field address */
2226 var_to_reg_int(s1, src->prev, REG_ITMP1);
2227 gen_nullptr_check(s1);
2229 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2230 var_to_reg_int(s2, src, REG_ITMP2);
2232 var_to_reg_flt(s2, src, REG_FTMP2);
2236 codegen_addpatchref(cd, mcodeptr,
2237 PATCHER_get_putfield,
2238 (unresolved_field *) iptr->target, 0);
2240 if (opt_showdisassemble)
2246 disp = ((fieldinfo *) (iptr->val.a))->offset;
2249 switch (iptr->op1) {
2251 M_IST(s2, s1, disp);
2254 M_LST(s2, s1, disp);
2257 M_AST(s2, s1, disp);
2260 M_FST(s2, s1, disp);
2263 M_DST(s2, s1, disp);
2268 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2269 /* val = value (in current instruction) */
2270 /* op1 = type, val.a = field address (in */
2271 /* following NOP) */
2273 var_to_reg_int(s1, src, REG_ITMP1);
2274 gen_nullptr_check(s1);
2276 if (!iptr[1].val.a) {
2277 codegen_addpatchref(cd, mcodeptr,
2278 PATCHER_get_putfield,
2279 (unresolved_field *) iptr[1].target, 0);
2281 if (opt_showdisassemble)
2287 disp = ((fieldinfo *) (iptr[1].val.a))->offset;
2290 switch (iptr[1].op1) {
2292 M_IST(REG_ZERO, s1, disp);
2295 M_LST(REG_ZERO, s1, disp);
2298 M_AST(REG_ZERO, s1, disp);
2301 M_FST(REG_ZERO, s1, disp);
2304 M_DST(REG_ZERO, s1, disp);
2310 /* branch operations **************************************************/
2312 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2314 var_to_reg_int(s1, src, REG_ITMP1);
2315 M_INTMOVE(s1, REG_ITMP1_XPTR);
2317 #ifdef ENABLE_VERIFIER
2319 codegen_addpatchref(cd, mcodeptr,
2320 PATCHER_athrow_areturn,
2321 (unresolved_class *) iptr->val.a, 0);
2323 if (opt_showdisassemble)
2326 #endif /* ENABLE_VERIFIER */
2328 disp = dseg_addaddress(cd, asm_handle_exception);
2329 M_ALD(REG_ITMP2, REG_PV, disp);
2330 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2331 M_NOP; /* nop ensures that XPC is less than the end */
2332 /* of basic block */
2336 case ICMD_GOTO: /* ... ==> ... */
2337 /* op1 = target JavaVM pc */
2339 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2343 case ICMD_JSR: /* ... ==> ... */
2344 /* op1 = target JavaVM pc */
2346 M_BSR(REG_ITMP1, 0);
2347 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2350 case ICMD_RET: /* ... ==> ... */
2351 /* op1 = local variable */
2353 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2354 if (var->flags & INMEMORY) {
2355 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2356 M_RET(REG_ZERO, REG_ITMP1);
2359 M_RET(REG_ZERO, var->regoff);
2363 case ICMD_IFNULL: /* ..., value ==> ... */
2364 /* op1 = target JavaVM pc */
2366 var_to_reg_int(s1, src, REG_ITMP1);
2368 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2371 case ICMD_IFNONNULL: /* ..., value ==> ... */
2372 /* op1 = target JavaVM pc */
2374 var_to_reg_int(s1, src, REG_ITMP1);
2376 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2379 case ICMD_IFEQ: /* ..., value ==> ... */
2380 /* op1 = target JavaVM pc, val.i = constant */
2382 var_to_reg_int(s1, src, REG_ITMP1);
2383 if (iptr->val.i == 0) {
2387 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2388 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2391 ICONST(REG_ITMP2, iptr->val.i);
2392 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2394 M_BNEZ(REG_ITMP1, 0);
2396 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2399 case ICMD_IFLT: /* ..., value ==> ... */
2400 /* op1 = target JavaVM pc, val.i = constant */
2402 var_to_reg_int(s1, src, REG_ITMP1);
2403 if (iptr->val.i == 0) {
2407 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2408 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2411 ICONST(REG_ITMP2, iptr->val.i);
2412 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2414 M_BNEZ(REG_ITMP1, 0);
2416 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2419 case ICMD_IFLE: /* ..., value ==> ... */
2420 /* op1 = target JavaVM pc, val.i = constant */
2422 var_to_reg_int(s1, src, REG_ITMP1);
2423 if (iptr->val.i == 0) {
2427 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2428 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2431 ICONST(REG_ITMP2, iptr->val.i);
2432 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2434 M_BNEZ(REG_ITMP1, 0);
2436 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2439 case ICMD_IFNE: /* ..., value ==> ... */
2440 /* op1 = target JavaVM pc, val.i = constant */
2442 var_to_reg_int(s1, src, REG_ITMP1);
2443 if (iptr->val.i == 0) {
2447 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2448 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2451 ICONST(REG_ITMP2, iptr->val.i);
2452 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2454 M_BEQZ(REG_ITMP1, 0);
2456 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2459 case ICMD_IFGT: /* ..., value ==> ... */
2460 /* op1 = target JavaVM pc, val.i = constant */
2462 var_to_reg_int(s1, src, REG_ITMP1);
2463 if (iptr->val.i == 0) {
2467 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2468 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2471 ICONST(REG_ITMP2, iptr->val.i);
2472 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2474 M_BEQZ(REG_ITMP1, 0);
2476 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2479 case ICMD_IFGE: /* ..., value ==> ... */
2480 /* op1 = target JavaVM pc, val.i = constant */
2482 var_to_reg_int(s1, src, REG_ITMP1);
2483 if (iptr->val.i == 0) {
2487 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2488 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2491 ICONST(REG_ITMP2, iptr->val.i);
2492 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2494 M_BEQZ(REG_ITMP1, 0);
2496 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2499 case ICMD_IF_LEQ: /* ..., value ==> ... */
2500 /* op1 = target JavaVM pc, val.l = constant */
2502 var_to_reg_int(s1, src, REG_ITMP1);
2503 if (iptr->val.l == 0) {
2507 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2508 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2511 LCONST(REG_ITMP2, iptr->val.l);
2512 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2514 M_BNEZ(REG_ITMP1, 0);
2516 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2519 case ICMD_IF_LLT: /* ..., value ==> ... */
2520 /* op1 = target JavaVM pc, val.l = constant */
2522 var_to_reg_int(s1, src, REG_ITMP1);
2523 if (iptr->val.l == 0) {
2527 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2528 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2531 LCONST(REG_ITMP2, iptr->val.l);
2532 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2534 M_BNEZ(REG_ITMP1, 0);
2536 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2539 case ICMD_IF_LLE: /* ..., value ==> ... */
2540 /* op1 = target JavaVM pc, val.l = constant */
2542 var_to_reg_int(s1, src, REG_ITMP1);
2543 if (iptr->val.l == 0) {
2547 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2548 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2551 LCONST(REG_ITMP2, iptr->val.l);
2552 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2554 M_BNEZ(REG_ITMP1, 0);
2556 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2559 case ICMD_IF_LNE: /* ..., value ==> ... */
2560 /* op1 = target JavaVM pc, val.l = constant */
2562 var_to_reg_int(s1, src, REG_ITMP1);
2563 if (iptr->val.l == 0) {
2567 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2568 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2571 LCONST(REG_ITMP2, iptr->val.l);
2572 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2574 M_BEQZ(REG_ITMP1, 0);
2576 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2579 case ICMD_IF_LGT: /* ..., value ==> ... */
2580 /* op1 = target JavaVM pc, val.l = constant */
2582 var_to_reg_int(s1, src, REG_ITMP1);
2583 if (iptr->val.l == 0) {
2587 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2588 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2591 LCONST(REG_ITMP2, iptr->val.l);
2592 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2594 M_BEQZ(REG_ITMP1, 0);
2596 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2599 case ICMD_IF_LGE: /* ..., value ==> ... */
2600 /* op1 = target JavaVM pc, val.l = constant */
2602 var_to_reg_int(s1, src, REG_ITMP1);
2603 if (iptr->val.l == 0) {
2607 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2608 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2611 LCONST(REG_ITMP2, iptr->val.l);
2612 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2614 M_BEQZ(REG_ITMP1, 0);
2616 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2619 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2620 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2621 case ICMD_IF_ACMPEQ:
2623 var_to_reg_int(s1, src->prev, REG_ITMP1);
2624 var_to_reg_int(s2, src, REG_ITMP2);
2625 M_CMPEQ(s1, s2, REG_ITMP1);
2626 M_BNEZ(REG_ITMP1, 0);
2627 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2630 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2631 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2632 case ICMD_IF_ACMPNE:
2634 var_to_reg_int(s1, src->prev, REG_ITMP1);
2635 var_to_reg_int(s2, src, REG_ITMP2);
2636 M_CMPEQ(s1, s2, REG_ITMP1);
2637 M_BEQZ(REG_ITMP1, 0);
2638 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2641 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2642 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2644 var_to_reg_int(s1, src->prev, REG_ITMP1);
2645 var_to_reg_int(s2, src, REG_ITMP2);
2646 M_CMPLT(s1, s2, REG_ITMP1);
2647 M_BNEZ(REG_ITMP1, 0);
2648 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2651 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2652 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2654 var_to_reg_int(s1, src->prev, REG_ITMP1);
2655 var_to_reg_int(s2, src, REG_ITMP2);
2656 M_CMPLE(s1, s2, REG_ITMP1);
2657 M_BEQZ(REG_ITMP1, 0);
2658 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2661 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2662 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2664 var_to_reg_int(s1, src->prev, REG_ITMP1);
2665 var_to_reg_int(s2, src, REG_ITMP2);
2666 M_CMPLE(s1, s2, REG_ITMP1);
2667 M_BNEZ(REG_ITMP1, 0);
2668 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2671 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2672 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2674 var_to_reg_int(s1, src->prev, REG_ITMP1);
2675 var_to_reg_int(s2, src, REG_ITMP2);
2676 M_CMPLT(s1, s2, REG_ITMP1);
2677 M_BEQZ(REG_ITMP1, 0);
2678 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2681 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2683 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2686 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2687 /* val.i = constant */
2689 var_to_reg_int(s1, src, REG_ITMP1);
2690 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2692 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2693 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2694 M_CMPEQ(s1, REG_ZERO, d);
2695 store_reg_to_var_int(iptr->dst, d);
2698 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2699 M_CMPEQ(s1, REG_ZERO, d);
2701 store_reg_to_var_int(iptr->dst, d);
2705 M_MOV(s1, REG_ITMP1);
2708 ICONST(d, iptr[1].val.i);
2710 if ((s3 >= 0) && (s3 <= 255)) {
2711 M_CMOVEQ_IMM(s1, s3, d);
2713 ICONST(REG_ITMP3, s3);
2714 M_CMOVEQ(s1, REG_ITMP3, d);
2716 store_reg_to_var_int(iptr->dst, d);
2719 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2720 /* val.i = constant */
2722 var_to_reg_int(s1, src, REG_ITMP1);
2723 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2725 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2726 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2727 M_CMPEQ(s1, REG_ZERO, d);
2728 store_reg_to_var_int(iptr->dst, d);
2731 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2732 M_CMPEQ(s1, REG_ZERO, d);
2734 store_reg_to_var_int(iptr->dst, d);
2738 M_MOV(s1, REG_ITMP1);
2741 ICONST(d, iptr[1].val.i);
2743 if ((s3 >= 0) && (s3 <= 255)) {
2744 M_CMOVNE_IMM(s1, s3, d);
2746 ICONST(REG_ITMP3, s3);
2747 M_CMOVNE(s1, REG_ITMP3, d);
2749 store_reg_to_var_int(iptr->dst, d);
2752 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2753 /* val.i = constant */
2755 var_to_reg_int(s1, src, REG_ITMP1);
2756 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2758 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2759 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2760 M_CMPLT(s1, REG_ZERO, d);
2761 store_reg_to_var_int(iptr->dst, d);
2764 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2765 M_CMPLE(REG_ZERO, s1, d);
2766 store_reg_to_var_int(iptr->dst, d);
2770 M_MOV(s1, REG_ITMP1);
2773 ICONST(d, iptr[1].val.i);
2775 if ((s3 >= 0) && (s3 <= 255)) {
2776 M_CMOVLT_IMM(s1, s3, d);
2778 ICONST(REG_ITMP3, s3);
2779 M_CMOVLT(s1, REG_ITMP3, d);
2781 store_reg_to_var_int(iptr->dst, d);
2784 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2785 /* val.i = constant */
2787 var_to_reg_int(s1, src, REG_ITMP1);
2788 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2790 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2791 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2792 M_CMPLE(REG_ZERO, s1, d);
2793 store_reg_to_var_int(iptr->dst, d);
2796 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2797 M_CMPLT(s1, REG_ZERO, d);
2798 store_reg_to_var_int(iptr->dst, d);
2802 M_MOV(s1, REG_ITMP1);
2805 ICONST(d, iptr[1].val.i);
2807 if ((s3 >= 0) && (s3 <= 255)) {
2808 M_CMOVGE_IMM(s1, s3, d);
2810 ICONST(REG_ITMP3, s3);
2811 M_CMOVGE(s1, REG_ITMP3, d);
2813 store_reg_to_var_int(iptr->dst, d);
2816 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2817 /* val.i = constant */
2819 var_to_reg_int(s1, src, REG_ITMP1);
2820 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2822 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2823 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2824 M_CMPLT(REG_ZERO, s1, d);
2825 store_reg_to_var_int(iptr->dst, d);
2828 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2829 M_CMPLE(s1, REG_ZERO, d);
2830 store_reg_to_var_int(iptr->dst, d);
2834 M_MOV(s1, REG_ITMP1);
2837 ICONST(d, iptr[1].val.i);
2839 if ((s3 >= 0) && (s3 <= 255)) {
2840 M_CMOVGT_IMM(s1, s3, d);
2842 ICONST(REG_ITMP3, s3);
2843 M_CMOVGT(s1, REG_ITMP3, d);
2845 store_reg_to_var_int(iptr->dst, d);
2848 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2849 /* val.i = constant */
2851 var_to_reg_int(s1, src, REG_ITMP1);
2852 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2854 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2855 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2856 M_CMPLE(s1, REG_ZERO, d);
2857 store_reg_to_var_int(iptr->dst, d);
2860 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2861 M_CMPLT(REG_ZERO, s1, d);
2862 store_reg_to_var_int(iptr->dst, d);
2866 M_MOV(s1, REG_ITMP1);
2869 ICONST(d, iptr[1].val.i);
2871 if ((s3 >= 0) && (s3 <= 255)) {
2872 M_CMOVLE_IMM(s1, s3, d);
2874 ICONST(REG_ITMP3, s3);
2875 M_CMOVLE(s1, REG_ITMP3, d);
2877 store_reg_to_var_int(iptr->dst, d);
2881 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2884 var_to_reg_int(s1, src, REG_RESULT);
2885 M_INTMOVE(s1, REG_RESULT);
2886 goto nowperformreturn;
2888 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2890 var_to_reg_int(s1, src, REG_RESULT);
2891 M_INTMOVE(s1, REG_RESULT);
2893 #ifdef ENABLE_VERIFIER
2895 codegen_addpatchref(cd, mcodeptr,
2896 PATCHER_athrow_areturn,
2897 (unresolved_class *) iptr->val.a, 0);
2899 if (opt_showdisassemble)
2902 #endif /* ENABLE_VERIFIER */
2903 goto nowperformreturn;
2905 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2908 var_to_reg_flt(s1, src, REG_FRESULT);
2909 M_FLTMOVE(s1, REG_FRESULT);
2910 goto nowperformreturn;
2912 case ICMD_RETURN: /* ... ==> ... */
2918 p = parentargs_base;
2920 /* call trace function */
2923 M_LDA(REG_SP, REG_SP, -3 * 8);
2924 M_AST(REG_RA, REG_SP, 0 * 8);
2925 M_LST(REG_RESULT, REG_SP, 1 * 8);
2926 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2928 disp = dseg_addaddress(cd, m);
2929 M_ALD(rd->argintregs[0], REG_PV, disp);
2930 M_MOV(REG_RESULT, rd->argintregs[1]);
2931 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2932 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2934 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2935 M_ALD(REG_PV, REG_PV, disp);
2936 M_JSR(REG_RA, REG_PV);
2937 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2938 M_LDA(REG_PV, REG_RA, -disp);
2940 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2941 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2942 M_ALD(REG_RA, REG_SP, 0 * 8);
2943 M_LDA(REG_SP, REG_SP, 3 * 8);
2946 #if defined(USE_THREADS)
2947 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2948 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2950 switch (iptr->opc) {
2954 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2958 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2962 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2963 M_ALD(REG_PV, REG_PV, disp);
2964 M_JSR(REG_RA, REG_PV);
2965 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2966 M_LDA(REG_PV, REG_RA, disp);
2968 switch (iptr->opc) {
2972 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2976 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2982 /* restore return address */
2984 if (!m->isleafmethod) {
2985 p--; M_LLD(REG_RA, REG_SP, p * 8);
2988 /* restore saved registers */
2990 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2991 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2993 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2994 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2997 /* deallocate stack */
2999 if (parentargs_base) {
3000 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
3003 M_RET(REG_ZERO, REG_RA);
3009 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3014 tptr = (void **) iptr->target;
3016 s4ptr = iptr->val.a;
3017 l = s4ptr[1]; /* low */
3018 i = s4ptr[2]; /* high */
3020 var_to_reg_int(s1, src, REG_ITMP1);
3022 M_INTMOVE(s1, REG_ITMP1);
3023 } else if (l <= 32768) {
3024 M_LDA(REG_ITMP1, s1, -l);
3026 ICONST(REG_ITMP2, l);
3027 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3034 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3036 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3037 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3039 M_BEQZ(REG_ITMP2, 0);
3040 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3042 /* build jump table top down and use address of lowest entry */
3044 /* s4ptr += 3 + i; */
3048 dseg_addtarget(cd, (basicblock *) tptr[0]);
3053 /* length of dataseg after last dseg_addtarget is used by load */
3055 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3056 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3057 M_JMP(REG_ZERO, REG_ITMP2);
3062 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3064 s4 i, l, val, *s4ptr;
3067 tptr = (void **) iptr->target;
3069 s4ptr = iptr->val.a;
3070 l = s4ptr[0]; /* default */
3071 i = s4ptr[1]; /* count */
3073 MCODECHECK((i<<2)+8);
3074 var_to_reg_int(s1, src, REG_ITMP1);
3080 if ((val >= 0) && (val <= 255)) {
3081 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3083 if ((val >= -32768) && (val <= 32767)) {
3084 M_LDA(REG_ITMP2, REG_ZERO, val);
3086 disp = dseg_adds4(cd, val);
3087 M_ILD(REG_ITMP2, REG_PV, disp);
3089 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3091 M_BNEZ(REG_ITMP2, 0);
3092 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3097 tptr = (void **) iptr->target;
3098 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3105 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3106 /* op1 = arg count val.a = builtintable entry */
3112 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3113 /* op1 = arg count, val.a = method pointer */
3115 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3116 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3117 case ICMD_INVOKEINTERFACE:
3122 unresolved_method *um = iptr->target;
3123 md = um->methodref->parseddesc.md;
3125 md = lm->parseddesc;
3129 s3 = md->paramcount;
3131 MCODECHECK((s3 << 1) + 64);
3133 /* copy arguments to registers or stack location */
3135 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3136 if (src->varkind == ARGVAR)
3138 if (IS_INT_LNG_TYPE(src->type)) {
3139 if (!md->params[s3].inmemory) {
3140 s1 = rd->argintregs[md->params[s3].regoff];
3141 var_to_reg_int(d, src, s1);
3144 var_to_reg_int(d, src, REG_ITMP1);
3145 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3149 if (!md->params[s3].inmemory) {
3150 s1 = rd->argfltregs[md->params[s3].regoff];
3151 var_to_reg_flt(d, src, s1);
3154 var_to_reg_flt(d, src, REG_FTMP1);
3155 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3160 switch (iptr->opc) {
3162 disp = dseg_addaddress(cd, bte->fp);
3163 d = md->returntype.type;
3165 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3166 M_JSR(REG_RA, REG_PV);
3167 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3168 M_LDA(REG_PV, REG_RA, -disp);
3170 /* if op1 == true, we need to check for an exception */
3172 if (iptr->op1 == true) {
3173 M_BEQZ(REG_RESULT, 0);
3174 codegen_addxexceptionrefs(cd, mcodeptr);
3178 case ICMD_INVOKESPECIAL:
3179 M_BEQZ(rd->argintregs[0], 0);
3180 codegen_addxnullrefs(cd, mcodeptr);
3183 case ICMD_INVOKESTATIC:
3185 unresolved_method *um = iptr->target;
3187 disp = dseg_addaddress(cd, NULL);
3189 codegen_addpatchref(cd, mcodeptr,
3190 PATCHER_invokestatic_special, um, disp);
3192 if (opt_showdisassemble)
3195 d = um->methodref->parseddesc.md->returntype.type;
3198 disp = dseg_addaddress(cd, lm->stubroutine);
3199 d = lm->parseddesc->returntype.type;
3202 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3203 M_JSR(REG_RA, REG_PV);
3204 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3205 M_LDA(REG_PV, REG_RA, -disp);
3208 case ICMD_INVOKEVIRTUAL:
3209 gen_nullptr_check(rd->argintregs[0]);
3212 unresolved_method *um = iptr->target;
3214 codegen_addpatchref(cd, mcodeptr,
3215 PATCHER_invokevirtual, um, 0);
3217 if (opt_showdisassemble)
3221 d = um->methodref->parseddesc.md->returntype.type;
3224 s1 = OFFSET(vftbl_t, table[0]) +
3225 sizeof(methodptr) * lm->vftblindex;
3226 d = lm->parseddesc->returntype.type;
3229 M_ALD(REG_METHODPTR, rd->argintregs[0],
3230 OFFSET(java_objectheader, vftbl));
3231 M_ALD(REG_PV, REG_METHODPTR, s1);
3232 M_JSR(REG_RA, REG_PV);
3233 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3234 M_LDA(REG_PV, REG_RA, -disp);
3237 case ICMD_INVOKEINTERFACE:
3238 gen_nullptr_check(rd->argintregs[0]);
3241 unresolved_method *um = iptr->target;
3243 codegen_addpatchref(cd, mcodeptr,
3244 PATCHER_invokeinterface, um, 0);
3246 if (opt_showdisassemble)
3251 d = um->methodref->parseddesc.md->returntype.type;
3254 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3255 sizeof(methodptr*) * lm->class->index;
3257 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3259 d = lm->parseddesc->returntype.type;
3262 M_ALD(REG_METHODPTR, rd->argintregs[0],
3263 OFFSET(java_objectheader, vftbl));
3264 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3265 M_ALD(REG_PV, REG_METHODPTR, s2);
3266 M_JSR(REG_RA, REG_PV);
3267 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3268 M_LDA(REG_PV, REG_RA, -disp);
3272 /* d contains return type */
3274 if (d != TYPE_VOID) {
3275 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3276 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3277 M_INTMOVE(REG_RESULT, s1);
3278 store_reg_to_var_int(iptr->dst, s1);
3280 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3281 M_FLTMOVE(REG_FRESULT, s1);
3282 store_reg_to_var_flt(iptr->dst, s1);
3288 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3290 /* op1: 0 == array, 1 == class */
3291 /* val.a: (classinfo*) superclass */
3293 /* superclass is an interface:
3295 * OK if ((sub == NULL) ||
3296 * (sub->vftbl->interfacetablelength > super->index) &&
3297 * (sub->vftbl->interfacetable[-super->index] != NULL));
3299 * superclass is a class:
3301 * OK if ((sub == NULL) || (0
3302 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3303 * super->vftbl->diffval));
3306 if (iptr->op1 == 1) {
3307 /* object type cast-check */
3310 vftbl_t *supervftbl;
3313 super = (classinfo *) iptr->val.a;
3320 superindex = super->index;
3321 supervftbl = super->vftbl;
3324 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3325 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3327 var_to_reg_int(s1, src, REG_ITMP1);
3329 /* calculate interface checkcast code size */
3333 s2 += opt_showdisassemble ? 1 : 0;
3335 /* calculate class checkcast code size */
3337 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3339 s3 += opt_showdisassemble ? 1 : 0;
3341 /* if class is not resolved, check which code to call */
3344 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3346 disp = dseg_adds4(cd, 0); /* super->flags */
3348 codegen_addpatchref(cd, mcodeptr,
3349 PATCHER_checkcast_instanceof_flags,
3350 (constant_classref *) iptr->target,
3353 if (opt_showdisassemble)
3356 M_ILD(REG_ITMP2, REG_PV, disp);
3357 disp = dseg_adds4(cd, ACC_INTERFACE);
3358 M_ILD(REG_ITMP3, REG_PV, disp);
3359 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3360 M_BEQZ(REG_ITMP2, s2 + 1);
3363 /* interface checkcast code */
3365 if (!super || (super->flags & ACC_INTERFACE)) {
3370 codegen_addpatchref(cd, mcodeptr,
3371 PATCHER_checkcast_instanceof_interface,
3372 (constant_classref *) iptr->target,
3375 if (opt_showdisassemble)
3379 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3380 M_ILD(REG_ITMP3, REG_ITMP2,
3381 OFFSET(vftbl_t, interfacetablelength));
3382 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3383 M_BLEZ(REG_ITMP3, 0);
3384 codegen_addxcastrefs(cd, mcodeptr);
3385 M_ALD(REG_ITMP3, REG_ITMP2,
3386 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3387 superindex * sizeof(methodptr*)));
3388 M_BEQZ(REG_ITMP3, 0);
3389 codegen_addxcastrefs(cd, mcodeptr);
3395 /* class checkcast code */
3397 if (!super || !(super->flags & ACC_INTERFACE)) {
3398 disp = dseg_addaddress(cd, supervftbl);
3404 codegen_addpatchref(cd, mcodeptr,
3405 PATCHER_checkcast_instanceof_class,
3406 (constant_classref *) iptr->target,
3409 if (opt_showdisassemble)
3413 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3414 M_ALD(REG_ITMP3, REG_PV, disp);
3415 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3416 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3418 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3419 /* if (s1 != REG_ITMP1) { */
3420 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3421 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3422 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3423 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3425 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3428 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3429 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3430 M_ALD(REG_ITMP3, REG_PV, disp);
3431 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3432 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3433 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3436 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3437 M_BEQZ(REG_ITMP3, 0);
3438 codegen_addxcastrefs(cd, mcodeptr);
3440 d = reg_of_var(rd, iptr->dst, s1);
3443 /* array type cast-check */
3445 var_to_reg_int(s1, src, rd->argintregs[0]);
3446 M_INTMOVE(s1, rd->argintregs[0]);
3448 disp = dseg_addaddress(cd, iptr->val.a);
3450 if (iptr->val.a == NULL) {
3451 codegen_addpatchref(cd, mcodeptr,
3452 PATCHER_builtin_arraycheckcast,
3453 (constant_classref *) iptr->target,
3456 if (opt_showdisassemble)
3460 M_ALD(rd->argintregs[1], REG_PV, disp);
3461 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3462 M_ALD(REG_PV, REG_PV, disp);
3463 M_JSR(REG_RA, REG_PV);
3464 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3465 M_LDA(REG_PV, REG_RA, -disp);
3467 M_BEQZ(REG_RESULT, 0);
3468 codegen_addxcastrefs(cd, mcodeptr);
3470 var_to_reg_int(s1, src, REG_ITMP1);
3471 d = reg_of_var(rd, iptr->dst, s1);
3474 store_reg_to_var_int(iptr->dst, d);
3477 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3479 /* op1: 0 == array, 1 == class */
3480 /* val.a: (classinfo*) superclass */
3482 /* superclass is an interface:
3484 * return (sub != NULL) &&
3485 * (sub->vftbl->interfacetablelength > super->index) &&
3486 * (sub->vftbl->interfacetable[-super->index] != NULL);
3488 * superclass is a class:
3490 * return ((sub != NULL) && (0
3491 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3492 * super->vftbl->diffvall));
3497 vftbl_t *supervftbl;
3500 super = (classinfo *) iptr->val.a;
3507 superindex = super->index;
3508 supervftbl = super->vftbl;
3511 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3512 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3514 var_to_reg_int(s1, src, REG_ITMP1);
3515 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3517 M_MOV(s1, REG_ITMP1);
3521 /* calculate interface instanceof code size */
3525 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3527 /* calculate class instanceof code size */
3531 s3 += (opt_showdisassemble ? 1 : 0);
3533 /* if class is not resolved, check which code to call */
3537 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3539 disp = dseg_adds4(cd, 0); /* super->flags */
3541 codegen_addpatchref(cd, mcodeptr,
3542 PATCHER_checkcast_instanceof_flags,
3543 (constant_classref *) iptr->target, disp);
3545 if (opt_showdisassemble)
3548 M_ILD(REG_ITMP3, REG_PV, disp);
3550 disp = dseg_adds4(cd, ACC_INTERFACE);
3551 M_ILD(REG_ITMP2, REG_PV, disp);
3552 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3553 M_BEQZ(REG_ITMP3, s2 + 1);
3556 /* interface instanceof code */
3558 if (!super || (super->flags & ACC_INTERFACE)) {
3564 /* If d == REG_ITMP2, then it's destroyed in check code */
3569 codegen_addpatchref(cd, mcodeptr,
3570 PATCHER_checkcast_instanceof_interface,
3571 (constant_classref *) iptr->target, 0);
3573 if (opt_showdisassemble)
3577 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3578 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3579 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3580 M_BLEZ(REG_ITMP3, 2);
3581 M_ALD(REG_ITMP1, REG_ITMP1,
3582 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3583 superindex * sizeof(methodptr*)));
3584 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3590 /* class instanceof code */
3592 if (!super || !(super->flags & ACC_INTERFACE)) {
3593 disp = dseg_addaddress(cd, supervftbl);
3600 codegen_addpatchref(cd, mcodeptr,
3601 PATCHER_checkcast_instanceof_class,
3602 (constant_classref *) iptr->target,
3605 if (opt_showdisassemble)
3609 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3610 M_ALD(REG_ITMP2, REG_PV, disp);
3611 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3612 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3614 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3615 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3616 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3617 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3618 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3620 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3621 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3623 store_reg_to_var_int(iptr->dst, d);
3627 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3628 /* op1 = dimension, val.a = array descriptor */
3630 /* check for negative sizes and copy sizes to stack if necessary */
3632 MCODECHECK((iptr->op1 << 1) + 64);
3634 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3635 /* copy SAVEDVAR sizes to stack */
3637 if (src->varkind != ARGVAR) {
3638 var_to_reg_int(s2, src, REG_ITMP1);
3639 M_LST(s2, REG_SP, s1 * 8);
3643 /* a0 = dimension count */
3645 ICONST(rd->argintregs[0], iptr->op1);
3647 /* is patcher function set? */
3650 disp = dseg_addaddress(cd, 0);
3652 codegen_addpatchref(cd, mcodeptr,
3653 (functionptr) iptr->target, iptr->val.a,
3656 if (opt_showdisassemble)
3660 disp = dseg_addaddress(cd, iptr->val.a);
3663 /* a1 = arraydescriptor */
3665 M_ALD(rd->argintregs[1], REG_PV, disp);
3667 /* a2 = pointer to dimensions = stack pointer */
3669 M_INTMOVE(REG_SP, rd->argintregs[2]);
3671 disp = dseg_addaddress(cd, (void *) BUILTIN_multianewarray);
3672 M_ALD(REG_PV, REG_PV, disp);
3673 M_JSR(REG_RA, REG_PV);
3674 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3675 M_LDA(REG_PV, REG_RA, -disp);
3677 /* check for exception before result assignment */
3679 M_BEQZ(REG_RESULT, 0);
3680 codegen_addxexceptionrefs(cd, mcodeptr);
3682 d = reg_of_var(rd, iptr->dst, REG_RESULT);
3683 M_INTMOVE(REG_RESULT, d);
3684 store_reg_to_var_int(iptr->dst, d);
3689 new_internalerror("Unknown ICMD %d", iptr->opc);
3693 } /* for instruction */
3695 /* copy values to interface registers */
3697 src = bptr->outstack;
3698 len = bptr->outdepth;
3705 if ((src->varkind != STACKVAR)) {
3707 if (IS_FLT_DBL_TYPE(s2)) {
3708 var_to_reg_flt(s1, src, REG_FTMP1);
3709 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3710 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3713 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3717 var_to_reg_int(s1, src, REG_ITMP1);
3718 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3719 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3722 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3728 } /* if (bptr -> flags >= BBREACHED) */
3729 } /* for basic block */
3731 codegen_createlinenumbertable(cd);
3735 s4 *xcodeptr = NULL;
3738 /* generate ArithmeticException stubs */
3740 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3741 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3743 (u1 *) mcodeptr - cd->mcodebase);
3747 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3749 if (xcodeptr != NULL) {
3750 disp = xcodeptr - mcodeptr - 1;
3754 xcodeptr = mcodeptr;
3756 M_MOV(REG_PV, rd->argintregs[0]);
3757 M_MOV(REG_SP, rd->argintregs[1]);
3758 M_ALD(rd->argintregs[2],
3759 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3760 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3762 M_LDA(REG_SP, REG_SP, -1 * 8);
3763 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3765 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3766 M_ALD(REG_PV, REG_PV, disp);
3767 M_JSR(REG_RA, REG_PV);
3768 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3769 M_LDA(REG_PV, REG_RA, -disp);
3771 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3773 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3774 M_LDA(REG_SP, REG_SP, 1 * 8);
3776 disp = dseg_addaddress(cd, asm_handle_exception);
3777 M_ALD(REG_ITMP3, REG_PV, disp);
3778 M_JMP(REG_ZERO, REG_ITMP3);
3782 /* generate ArrayIndexOutOfBoundsException stubs */
3786 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3787 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3789 (u1*) mcodeptr - cd->mcodebase);
3793 /* move index register into REG_ITMP1 */
3795 M_MOV(bref->reg, REG_ITMP1);
3796 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3798 if (xcodeptr != NULL) {
3799 disp = xcodeptr - mcodeptr - 1;
3803 xcodeptr = mcodeptr;
3805 M_MOV(REG_PV, rd->argintregs[0]);
3806 M_MOV(REG_SP, rd->argintregs[1]);
3808 if (m->isleafmethod)
3809 M_MOV(REG_RA, rd->argintregs[2]);
3811 M_ALD(rd->argintregs[2],
3812 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3814 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3815 M_MOV(REG_ITMP1, rd->argintregs[4]);
3817 M_LDA(REG_SP, REG_SP, -2 * 8);
3818 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3820 if (m->isleafmethod)
3821 M_AST(REG_RA, REG_SP, 1 * 8);
3823 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3824 M_ALD(REG_PV, REG_PV, disp);
3825 M_JSR(REG_RA, REG_PV);
3826 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3827 M_LDA(REG_PV, REG_RA, -disp);
3829 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3831 if (m->isleafmethod)
3832 M_ALD(REG_RA, REG_SP, 1 * 8);
3834 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3835 M_LDA(REG_SP, REG_SP, 2 * 8);
3837 disp = dseg_addaddress(cd, asm_handle_exception);
3838 M_ALD(REG_ITMP3, REG_PV, disp);
3839 M_JMP(REG_ZERO, REG_ITMP3);
3843 /* generate ArrayStoreException stubs */
3847 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3848 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3850 (u1 *) mcodeptr - cd->mcodebase);
3854 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3856 if (xcodeptr != NULL) {
3857 disp = xcodeptr - mcodeptr - 1;
3861 xcodeptr = mcodeptr;
3863 M_MOV(REG_PV, rd->argintregs[0]);
3864 M_MOV(REG_SP, rd->argintregs[1]);
3865 M_ALD(rd->argintregs[2],
3866 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3867 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3869 M_LDA(REG_SP, REG_SP, -1 * 8);
3870 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3872 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3873 M_ALD(REG_PV, REG_PV, disp);
3874 M_JSR(REG_RA, REG_PV);
3875 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3876 M_LDA(REG_PV, REG_RA, -disp);
3878 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3880 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3881 M_LDA(REG_SP, REG_SP, 1 * 8);
3883 disp = dseg_addaddress(cd, asm_handle_exception);
3884 M_ALD(REG_ITMP3, REG_PV, disp);
3885 M_JMP(REG_ZERO, REG_ITMP3);
3889 /* generate ClassCastException stubs */
3893 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3894 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3896 (u1 *) mcodeptr - cd->mcodebase);
3900 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3902 if (xcodeptr != NULL) {
3903 disp = xcodeptr - mcodeptr - 1;
3907 xcodeptr = mcodeptr;
3909 M_MOV(REG_PV, rd->argintregs[0]);
3910 M_MOV(REG_SP, rd->argintregs[1]);
3912 if (m->isleafmethod)
3913 M_MOV(REG_RA, rd->argintregs[2]);
3915 M_ALD(rd->argintregs[2],
3916 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3918 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3920 M_LDA(REG_SP, REG_SP, -2 * 8);
3921 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3923 if (m->isleafmethod)
3924 M_AST(REG_RA, REG_SP, 1 * 8);
3926 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3927 M_ALD(REG_PV, REG_PV, disp);
3928 M_JSR(REG_RA, REG_PV);
3929 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3930 M_LDA(REG_PV, REG_RA, -disp);
3932 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3934 if (m->isleafmethod)
3935 M_ALD(REG_RA, REG_SP, 1 * 8);
3937 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3938 M_LDA(REG_SP, REG_SP, 2 * 8);
3940 disp = dseg_addaddress(cd, asm_handle_exception);
3941 M_ALD(REG_ITMP3, REG_PV, disp);
3942 M_JMP(REG_ZERO, REG_ITMP3);
3946 /* generate NullPointerException stubs */
3950 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3951 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3953 (u1 *) mcodeptr - cd->mcodebase);
3957 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3959 if (xcodeptr != NULL) {
3960 disp = xcodeptr - mcodeptr - 1;
3964 xcodeptr = mcodeptr;
3966 M_MOV(REG_PV, rd->argintregs[0]);
3967 M_MOV(REG_SP, rd->argintregs[1]);
3969 if (m->isleafmethod)
3970 M_MOV(REG_RA, rd->argintregs[2]);
3972 M_ALD(rd->argintregs[2],
3973 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3975 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3977 M_LDA(REG_SP, REG_SP, -2 * 8);
3978 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3980 if (m->isleafmethod)
3981 M_AST(REG_RA, REG_SP, 1 * 8);
3983 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
3984 M_ALD(REG_PV, REG_PV, disp);
3985 M_JSR(REG_RA, REG_PV);
3986 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3987 M_LDA(REG_PV, REG_RA, -disp);
3989 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3991 if (m->isleafmethod)
3992 M_ALD(REG_RA, REG_SP, 1 * 8);
3994 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3995 M_LDA(REG_SP, REG_SP, 2 * 8);
3997 disp = dseg_addaddress(cd, asm_handle_exception);
3998 M_ALD(REG_ITMP3, REG_PV, disp);
3999 M_JMP(REG_ZERO, REG_ITMP3);
4003 /* generate exception check stubs */
4007 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4008 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4010 (u1 *) mcodeptr - cd->mcodebase);
4014 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4016 if (xcodeptr != NULL) {
4017 disp = xcodeptr - mcodeptr - 1;
4021 xcodeptr = mcodeptr;
4023 M_MOV(REG_PV, rd->argintregs[0]);
4024 M_MOV(REG_SP, rd->argintregs[1]);
4025 M_ALD(rd->argintregs[2],
4026 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4027 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4029 M_LDA(REG_SP, REG_SP, -1 * 8);
4030 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4032 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4033 M_ALD(REG_PV, REG_PV, disp);
4034 M_JSR(REG_RA, REG_PV);
4035 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4036 M_LDA(REG_PV, REG_RA, -disp);
4038 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4040 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4041 M_LDA(REG_SP, REG_SP, 1 * 8);
4043 disp = dseg_addaddress(cd, asm_handle_exception);
4044 M_ALD(REG_ITMP3, REG_PV, disp);
4045 M_JMP(REG_ZERO, REG_ITMP3);
4049 /* generate patcher stub call code */
4056 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4057 /* check code segment size */
4061 /* Get machine code which is patched back in later. The call is */
4062 /* 1 instruction word long. */
4064 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4067 /* patch in the call to call the following code (done at compile */
4070 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4071 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4073 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4075 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4077 /* create stack frame */
4079 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4081 /* move return address onto stack */
4083 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4085 /* move pointer to java_objectheader onto stack */
4087 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4088 /* create a virtual java_objectheader */
4090 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4091 disp = dseg_addaddress(cd, NULL); /* vftbl */
4093 M_LDA(REG_ITMP3, REG_PV, disp);
4094 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4099 /* move machine code onto stack */
4101 disp = dseg_adds4(cd, mcode);
4102 M_ILD(REG_ITMP3, REG_PV, disp);
4103 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4105 /* move class/method/field reference onto stack */
4107 disp = dseg_addaddress(cd, pref->ref);
4108 M_ALD(REG_ITMP3, REG_PV, disp);
4109 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4111 /* move data segment displacement onto stack */
4113 disp = dseg_adds4(cd, pref->disp);
4114 M_ILD(REG_ITMP3, REG_PV, disp);
4115 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4117 /* move patcher function pointer onto stack */
4119 disp = dseg_addaddress(cd, pref->patcher);
4120 M_ALD(REG_ITMP3, REG_PV, disp);
4121 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4123 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4124 M_ALD(REG_ITMP3, REG_PV, disp);
4125 M_JMP(REG_ZERO, REG_ITMP3);
4130 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4132 /* everything's ok */
4138 /* createcompilerstub **********************************************************
4140 Creates a stub routine which calls the compiler.
4142 *******************************************************************************/
4144 #define COMPSTUBSIZE 3
4146 u1 *createcompilerstub(methodinfo *m)
4148 u8 *s = CNEW(u8, COMPSTUBSIZE); /* memory to hold the stub */
4149 s4 *mcodeptr = (s4 *) s; /* code generation pointer */
4151 /* code for the stub */
4152 M_ALD(REG_PV, REG_PV, 16); /* load pointer to the compiler */
4153 M_JMP(0, REG_PV); /* jump to the compiler, return address
4154 in reg 0 is used as method pointer */
4155 s[1] = (ptrint) m; /* literals to be adressed */
4156 s[2] = (ptrint) asm_call_jit_compiler; /* jump directly via PV from above */
4158 #if defined(STATISTICS)
4160 count_cstub_len += COMPSTUBSIZE * 8;
4167 /* createnativestub ************************************************************
4169 Creates a stub routine which calls a native method.
4171 *******************************************************************************/
4173 u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4174 registerdata *rd, methoddesc *nmd)
4176 s4 *mcodeptr; /* code generation pointer */
4177 s4 stackframesize; /* size of stackframe if needed */
4180 s4 i, j; /* count variables */
4183 s4 funcdisp; /* displacement of the function */
4185 /* initialize variables */
4188 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4191 /* calculate stack frame size */
4194 1 + /* return address */
4195 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4196 sizeof(localref_table) / SIZEOF_VOID_P +
4197 1 + /* methodinfo for call trace */
4198 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4202 /* create method header */
4204 (void) dseg_addaddress(cd, m); /* MethodPointer */
4205 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4206 (void) dseg_adds4(cd, 0); /* IsSync */
4207 (void) dseg_adds4(cd, 0); /* IsLeaf */
4208 (void) dseg_adds4(cd, 0); /* IntSave */
4209 (void) dseg_adds4(cd, 0); /* FltSave */
4210 (void) dseg_addlinenumbertablesize(cd);
4211 (void) dseg_adds4(cd, 0); /* ExTableSize */
4214 /* initialize mcode variables */
4216 mcodeptr = (s4 *) cd->mcodeptr;
4219 /* generate stub code */
4221 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4222 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4225 /* call trace function */
4228 /* save integer argument registers */
4230 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4231 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4232 M_LST(rd->argintregs[i], REG_SP, j * 8);
4237 /* save and copy float arguments into integer registers */
4239 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4240 t = md->paramtypes[i].type;
4242 if (IS_FLT_DBL_TYPE(t)) {
4243 if (IS_2_WORD_TYPE(t)) {
4244 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4245 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4247 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4248 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4254 disp = dseg_addaddress(cd, m);
4255 M_ALD(REG_ITMP1, REG_PV, disp);
4256 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4257 disp = dseg_addaddress(cd, builtin_trace_args);
4258 M_ALD(REG_PV, REG_PV, disp);
4259 M_JSR(REG_RA, REG_PV);
4260 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4261 M_LDA(REG_PV, REG_RA, -disp);
4263 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4264 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4265 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4270 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4271 t = md->paramtypes[i].type;
4273 if (IS_FLT_DBL_TYPE(t)) {
4274 if (IS_2_WORD_TYPE(t)) {
4275 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4277 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4284 /* get function address (this must happen before the stackframeinfo) */
4286 funcdisp = dseg_addaddress(cd, f);
4288 #if !defined(ENABLE_STATICVM)
4290 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4292 if (opt_showdisassemble)
4297 /* save integer and float argument registers */
4299 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4300 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4301 M_LST(rd->argintregs[i], REG_SP, j * 8);
4306 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4307 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4308 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4313 /* prepare data structures for native function call */
4315 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4316 M_MOV(REG_PV, rd->argintregs[1]);
4317 M_LDA(rd->argintregs[2], REG_SP, stackframesize * 8);
4318 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4319 disp = dseg_addaddress(cd, codegen_start_native_call);
4320 M_ALD(REG_PV, REG_PV, disp);
4321 M_JSR(REG_RA, REG_PV);
4322 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4323 M_LDA(REG_PV, REG_RA, -disp);
4325 /* restore integer and float argument registers */
4327 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4328 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4329 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4334 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4335 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4336 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4341 /* copy or spill arguments to new locations */
4343 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4344 t = md->paramtypes[i].type;
4346 if (IS_INT_LNG_TYPE(t)) {
4347 if (!md->params[i].inmemory) {
4348 s1 = rd->argintregs[md->params[i].regoff];
4350 if (!nmd->params[j].inmemory) {
4351 s2 = rd->argintregs[nmd->params[j].regoff];
4355 s2 = nmd->params[j].regoff;
4356 M_LST(s1, REG_SP, s2 * 8);
4360 s1 = md->params[i].regoff + stackframesize;
4361 s2 = nmd->params[j].regoff;
4362 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4363 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4367 if (!md->params[i].inmemory) {
4368 s1 = rd->argfltregs[md->params[i].regoff];
4370 if (!nmd->params[j].inmemory) {
4371 s2 = rd->argfltregs[nmd->params[j].regoff];
4375 s2 = nmd->params[j].regoff;
4376 if (IS_2_WORD_TYPE(t))
4377 M_DST(s1, REG_SP, s2 * 8);
4379 M_FST(s1, REG_SP, s2 * 8);
4383 s1 = md->params[i].regoff + stackframesize;
4384 s2 = nmd->params[j].regoff;
4385 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4386 if (IS_2_WORD_TYPE(t))
4387 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4389 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4394 /* put class into second argument register */
4396 if (m->flags & ACC_STATIC) {
4397 disp = dseg_addaddress(cd, m->class);
4398 M_ALD(rd->argintregs[1], REG_PV, disp);
4401 /* put env into first argument register */
4403 disp = dseg_addaddress(cd, &env);
4404 M_ALD(rd->argintregs[0], REG_PV, disp);
4406 /* do the native function call */
4408 M_ALD(REG_PV, REG_PV, funcdisp);
4409 M_JSR(REG_RA, REG_PV); /* call native method */
4410 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4411 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4413 /* save return value */
4415 if (IS_INT_LNG_TYPE(md->returntype.type))
4416 M_LST(REG_RESULT, REG_SP, 0 * 8);
4418 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4420 /* remove native stackframe info */
4422 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4423 disp = dseg_addaddress(cd, codegen_finish_native_call);
4424 M_ALD(REG_PV, REG_PV, disp);
4425 M_JSR(REG_RA, REG_PV);
4426 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4427 M_LDA(REG_PV, REG_RA, -disp);
4429 /* call finished trace */
4432 /* just restore the value we need, don't care about the other */
4434 if (IS_INT_LNG_TYPE(md->returntype.type))
4435 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4437 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4439 disp = dseg_addaddress(cd, m);
4440 M_ALD(rd->argintregs[0], REG_PV, disp);
4442 M_MOV(REG_RESULT, rd->argintregs[1]);
4443 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4444 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4446 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4447 M_ALD(REG_PV, REG_PV, disp);
4448 M_JSR(REG_RA, REG_PV);
4449 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4450 M_LDA(REG_PV, REG_RA, -disp);
4453 /* check for exception */
4455 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4456 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4457 M_ALD(REG_PV, REG_PV, disp);
4458 M_JSR(REG_RA, REG_PV);
4459 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4460 M_LDA(REG_PV, REG_RA, -disp);
4461 M_MOV(REG_RESULT, REG_ITMP3);
4463 disp = dseg_addaddress(cd, &_exceptionptr);
4464 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4466 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4468 /* restore return value */
4470 if (IS_INT_LNG_TYPE(md->returntype.type))
4471 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4473 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4475 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4477 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4478 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4479 M_RET(REG_ZERO, REG_RA); /* return to caller */
4481 /* handle exception */
4483 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4485 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4486 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4488 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4490 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4491 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4492 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4495 /* process patcher calls **************************************************/
4503 /* there can only be one <clinit> ref entry */
4504 pref = cd->patchrefs;
4506 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4507 /* Get machine code which is patched back in later. The call is */
4508 /* 1 instruction word long. */
4510 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4511 mcode = (u4) *xcodeptr;
4513 /* patch in the call to call the following code (done at compile */
4516 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4517 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4519 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4521 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4523 /* create stack frame */
4525 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4527 /* move return address onto stack */
4529 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4531 /* move pointer to java_objectheader onto stack */
4533 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4534 /* create a virtual java_objectheader */
4536 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4537 disp = dseg_addaddress(cd, NULL); /* vftbl */
4539 M_LDA(REG_ITMP3, REG_PV, disp);
4540 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4542 M_AST(REG_ZERO, REG_SP, 4 * 8);
4545 /* move machine code onto stack */
4547 disp = dseg_adds4(cd, mcode);
4548 M_ILD(REG_ITMP3, REG_PV, disp);
4549 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4551 /* move class/method/field reference onto stack */
4553 disp = dseg_addaddress(cd, pref->ref);
4554 M_ALD(REG_ITMP3, REG_PV, disp);
4555 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4557 /* move data segment displacement onto stack */
4559 disp = dseg_adds4(cd, pref->disp);
4560 M_ILD(REG_ITMP3, REG_PV, disp);
4561 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4563 /* move patcher function pointer onto stack */
4565 disp = dseg_addaddress(cd, pref->patcher);
4566 M_ALD(REG_ITMP3, REG_PV, disp);
4567 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4569 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4570 M_ALD(REG_ITMP3, REG_PV, disp);
4571 M_JMP(REG_ZERO, REG_ITMP3);
4575 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4577 return m->entrypoint;
4582 * These are local overrides for various environment variables in Emacs.
4583 * Please do not remove this and leave it at the end of the file, where
4584 * Emacs will automagically detect them.
4585 * ---------------------------------------------------------------------
4588 * indent-tabs-mode: t