1 /* src/vm/jit/alpha/codegen.c - machine code generator for Alpha
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
25 Contact: cacao@cacaojvm.org
27 Authors: Andreas Krall
30 Changes: Joseph Wenninger
35 $Id: codegen.c 4550 2006-03-01 17:00:33Z twisti $
49 #include "vm/jit/alpha/arch.h"
50 #include "vm/jit/alpha/codegen.h"
52 #include "native/jni.h"
53 #include "native/native.h"
54 #include "vm/builtin.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/options.h"
59 #include "vm/stringlocal.h"
61 #include "vm/jit/asmpart.h"
62 #include "vm/jit/codegen-common.h"
63 #include "vm/jit/dseg.h"
64 #include "vm/jit/jit.h"
65 #include "vm/jit/parse.h"
66 #include "vm/jit/patcher.h"
67 #include "vm/jit/reg.h"
69 #if defined(ENABLE_LSRA)
70 # include "vm/jit/allocator/lsra.h"
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 /* create stack frame (if necessary) */
162 M_LDA(REG_SP, REG_SP, -parentargs_base * 8);
164 /* save return address and used callee saved registers */
167 if (!m->isleafmethod) {
168 p--; M_AST(REG_RA, REG_SP, p * 8);
170 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
171 p--; M_LST(rd->savintregs[i], REG_SP, p * 8);
173 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
174 p--; M_DST(rd->savfltregs[i], REG_SP, p * 8);
177 /* take arguments out of register or stack frame */
181 for (p = 0, l = 0; p < md->paramcount; p++) {
182 t = md->paramtypes[p].type;
183 var = &(rd->locals[l][t]);
185 if (IS_2_WORD_TYPE(t)) /* increment local counter for 2 word types */
189 s1 = md->params[p].regoff;
190 if (IS_INT_LNG_TYPE(t)) { /* integer args */
191 if (!md->params[p].inmemory) { /* register arguments */
192 s2 = rd->argintregs[s1];
193 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
194 M_INTMOVE(s2, var->regoff);
196 } else { /* reg arg -> spilled */
197 M_LST(s2, REG_SP, var->regoff * 8);
200 } else { /* stack arguments */
201 if (!(var->flags & INMEMORY)) { /* stack arg -> register */
202 M_LLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
204 } else { /* stack arg -> spilled */
205 var->regoff = parentargs_base + s1;
209 } else { /* floating args */
210 if (!md->params[p].inmemory) { /* register arguments */
211 s2 = rd->argfltregs[s1];
212 if (!(var->flags & INMEMORY)) { /* reg arg -> register */
213 M_FLTMOVE(s2, var->regoff);
215 } else { /* reg arg -> spilled */
216 M_DST(s2, REG_SP, var->regoff * 8);
219 } else { /* stack arguments */
220 if (!(var->flags & INMEMORY)) { /* stack-arg -> register */
221 M_DLD(var->regoff, REG_SP, (parentargs_base + s1) * 8);
223 } else { /* stack-arg -> spilled */
224 var->regoff = parentargs_base + s1;
230 /* call monitorenter function */
232 #if defined(USE_THREADS)
233 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
234 /* stack offset for monitor argument */
238 if (opt_verbosecall) {
239 M_LDA(REG_SP, REG_SP, -(INT_ARG_CNT + FLT_ARG_CNT) * 8);
241 for (p = 0; p < INT_ARG_CNT; p++)
242 M_LST(rd->argintregs[p], REG_SP, p * 8);
244 for (p = 0; p < FLT_ARG_CNT; p++)
245 M_DST(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
247 s1 += INT_ARG_CNT + FLT_ARG_CNT;
250 /* decide which monitor enter function to call */
252 if (m->flags & ACC_STATIC) {
253 disp = dseg_addaddress(cd, m->class);
254 M_ALD(rd->argintregs[0], REG_PV, disp);
255 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
256 disp = dseg_addaddress(cd, BUILTIN_staticmonitorenter);
257 M_ALD(REG_PV, REG_PV, disp);
258 M_JSR(REG_RA, REG_PV);
259 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
260 M_LDA(REG_PV, REG_RA, disp);
263 M_BEQZ(rd->argintregs[0], 0);
264 codegen_addxnullrefs(cd, mcodeptr);
265 M_AST(rd->argintregs[0], REG_SP, s1 * 8);
266 disp = dseg_addaddress(cd, BUILTIN_monitorenter);
267 M_ALD(REG_PV, REG_PV, disp);
268 M_JSR(REG_RA, REG_PV);
269 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
270 M_LDA(REG_PV, REG_RA, disp);
273 if (opt_verbosecall) {
274 for (p = 0; p < INT_ARG_CNT; p++)
275 M_LLD(rd->argintregs[p], REG_SP, p * 8);
277 for (p = 0; p < FLT_ARG_CNT; p++)
278 M_DLD(rd->argfltregs[p], REG_SP, (INT_ARG_CNT + p) * 8);
280 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT) * 8);
285 /* call trace function */
287 if (opt_verbosecall) {
288 M_LDA(REG_SP, REG_SP, -((INT_ARG_CNT + FLT_ARG_CNT + 2) * 8));
289 M_AST(REG_RA, REG_SP, 1 * 8);
291 /* save integer argument registers */
293 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
294 M_LST(rd->argintregs[p], REG_SP, (2 + p) * 8);
296 /* save and copy float arguments into integer registers */
298 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
299 t = md->paramtypes[p].type;
301 if (IS_FLT_DBL_TYPE(t)) {
302 if (IS_2_WORD_TYPE(t)) {
303 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
306 M_FST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
309 M_LLD(rd->argintregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
312 M_DST(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
316 disp = dseg_addaddress(cd, m);
317 M_ALD(REG_ITMP1, REG_PV, disp);
318 M_AST(REG_ITMP1, REG_SP, 0 * 8);
319 disp = dseg_addaddress(cd, (void *) builtin_trace_args);
320 M_ALD(REG_PV, REG_PV, disp);
321 M_JSR(REG_RA, REG_PV);
322 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
323 M_LDA(REG_PV, REG_RA, disp);
324 M_ALD(REG_RA, REG_SP, 1 * 8);
326 /* restore integer argument registers */
328 for (p = 0; p < md->paramcount && p < INT_ARG_CNT; p++)
329 M_LLD(rd->argintregs[p], REG_SP, (2 + p) * 8);
331 /* restore float argument registers */
333 for (p = 0; p < md->paramcount && p < FLT_ARG_CNT; p++) {
334 t = md->paramtypes[p].type;
336 if (IS_FLT_DBL_TYPE(t)) {
337 if (IS_2_WORD_TYPE(t)) {
338 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
341 M_FLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
345 M_DLD(rd->argfltregs[p], REG_SP, (2 + INT_ARG_CNT + p) * 8);
349 M_LDA(REG_SP, REG_SP, (INT_ARG_CNT + FLT_ARG_CNT + 2) * 8);
354 /* end of header generation */
356 /* walk through all basic blocks */
358 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
360 bptr->mpc = (s4) ((u1 *) mcodeptr - cd->mcodebase);
362 if (bptr->flags >= BBREACHED) {
364 /* branch resolving */
368 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
369 gen_resolvebranch((u1*) cd->mcodebase + brefs->branchpos,
370 brefs->branchpos, bptr->mpc);
374 /* copy interface registers to their destination */
379 #if defined(ENABLE_LSRA)
381 while (src != NULL) {
383 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
384 /* d = reg_of_var(m, src, REG_ITMP1); */
385 if (!(src->flags & INMEMORY))
389 M_INTMOVE(REG_ITMP1, d);
390 store_reg_to_var_int(src, d);
396 while (src != NULL) {
398 if ((len == 0) && (bptr->type != BBTYPE_STD)) {
399 d = reg_of_var(rd, src, REG_ITMP1);
400 M_INTMOVE(REG_ITMP1, d);
401 store_reg_to_var_int(src, d);
403 d = reg_of_var(rd, src, REG_IFTMP);
404 if ((src->varkind != STACKVAR)) {
406 if (IS_FLT_DBL_TYPE(s2)) {
407 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
408 s1 = rd->interfaces[len][s2].regoff;
411 M_DLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
413 store_reg_to_var_flt(src, d);
416 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
417 s1 = rd->interfaces[len][s2].regoff;
420 M_LLD(d, REG_SP, rd->interfaces[len][s2].regoff * 8);
422 store_reg_to_var_int(src, d);
428 #if defined(ENABLE_LSRA)
432 /* walk through all instructions */
437 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
438 if (iptr->line != currentline) {
439 dseg_addlinenumber(cd, iptr->line, (u1 *) mcodeptr);
440 currentline = iptr->line;
443 MCODECHECK(64); /* an instruction usually needs < 64 words */
446 case ICMD_INLINE_START:
447 case ICMD_INLINE_END:
450 case ICMD_NOP: /* ... ==> ... */
453 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
455 var_to_reg_int(s1, src, REG_ITMP1);
457 codegen_addxnullrefs(cd, mcodeptr);
460 /* constant operations ************************************************/
462 case ICMD_ICONST: /* ... ==> ..., constant */
463 /* op1 = 0, val.i = constant */
465 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
466 ICONST(d, iptr->val.i);
467 store_reg_to_var_int(iptr->dst, d);
470 case ICMD_LCONST: /* ... ==> ..., constant */
471 /* op1 = 0, val.l = constant */
473 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
474 LCONST(d, iptr->val.l);
475 store_reg_to_var_int(iptr->dst, d);
478 case ICMD_FCONST: /* ... ==> ..., constant */
479 /* op1 = 0, val.f = constant */
481 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
482 disp = dseg_addfloat(cd, iptr->val.f);
483 M_FLD(d, REG_PV, disp);
484 store_reg_to_var_flt(iptr->dst, d);
487 case ICMD_DCONST: /* ... ==> ..., constant */
488 /* op1 = 0, val.d = constant */
490 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
491 disp = dseg_adddouble(cd, iptr->val.d);
492 M_DLD(d, REG_PV, disp);
493 store_reg_to_var_flt(iptr->dst, d);
496 case ICMD_ACONST: /* ... ==> ..., constant */
497 /* op1 = 0, val.a = constant */
499 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
501 if ((iptr->target != NULL) && (iptr->val.a == NULL)) {
502 disp = dseg_addaddress(cd, iptr->val.a);
504 codegen_addpatchref(cd, mcodeptr,
506 (unresolved_class *) iptr->target, disp);
508 if (opt_showdisassemble)
511 M_ALD(d, REG_PV, disp);
514 if (iptr->val.a == NULL) {
515 M_INTMOVE(REG_ZERO, d);
517 disp = dseg_addaddress(cd, iptr->val.a);
518 M_ALD(d, REG_PV, disp);
521 store_reg_to_var_int(iptr->dst, d);
525 /* load/store operations **********************************************/
527 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
528 case ICMD_LLOAD: /* op1 = local variable */
531 d = reg_of_var(rd, iptr->dst, REG_ITMP1);
532 if ((iptr->dst->varkind == LOCALVAR) &&
533 (iptr->dst->varnum == iptr->op1))
535 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
536 if (var->flags & INMEMORY) {
537 M_LLD(d, REG_SP, var->regoff * 8);
539 M_INTMOVE(var->regoff, d);
541 store_reg_to_var_int(iptr->dst, d);
544 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
545 case ICMD_DLOAD: /* op1 = local variable */
547 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
548 if ((iptr->dst->varkind == LOCALVAR) &&
549 (iptr->dst->varnum == iptr->op1))
551 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ILOAD]);
552 if (var->flags & INMEMORY) {
553 M_DLD(d, REG_SP, var->regoff * 8);
555 M_FLTMOVE(var->regoff, d);
557 store_reg_to_var_flt(iptr->dst, d);
561 case ICMD_ISTORE: /* ..., value ==> ... */
562 case ICMD_LSTORE: /* op1 = local variable */
565 if ((src->varkind == LOCALVAR) &&
566 (src->varnum == iptr->op1))
568 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
569 if (var->flags & INMEMORY) {
570 var_to_reg_int(s1, src, REG_ITMP1);
571 M_LST(s1, REG_SP, var->regoff * 8);
573 var_to_reg_int(s1, src, var->regoff);
574 M_INTMOVE(s1, var->regoff);
578 case ICMD_FSTORE: /* ..., value ==> ... */
579 case ICMD_DSTORE: /* op1 = local variable */
581 if ((src->varkind == LOCALVAR) &&
582 (src->varnum == iptr->op1))
584 var = &(rd->locals[iptr->op1][iptr->opc - ICMD_ISTORE]);
585 if (var->flags & INMEMORY) {
586 var_to_reg_flt(s1, src, REG_FTMP1);
587 M_DST(s1, REG_SP, var->regoff * 8);
589 var_to_reg_flt(s1, src, var->regoff);
590 M_FLTMOVE(s1, var->regoff);
595 /* pop/dup/swap operations ********************************************/
597 /* attention: double and longs are only one entry in CACAO ICMDs */
599 case ICMD_POP: /* ..., value ==> ... */
600 case ICMD_POP2: /* ..., value, value ==> ... */
603 case ICMD_DUP: /* ..., a ==> ..., a, a */
604 M_COPY(src, iptr->dst);
607 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
609 M_COPY(src, iptr->dst);
610 M_COPY(src->prev, iptr->dst->prev);
611 M_COPY(iptr->dst, iptr->dst->prev->prev);
614 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
616 M_COPY(src, iptr->dst);
617 M_COPY(src->prev, iptr->dst->prev);
618 M_COPY(src->prev->prev, iptr->dst->prev->prev);
619 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
622 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
624 M_COPY(src, iptr->dst);
625 M_COPY(src->prev, iptr->dst->prev);
628 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
630 M_COPY(src, iptr->dst);
631 M_COPY(src->prev, iptr->dst->prev);
632 M_COPY(src->prev->prev, iptr->dst->prev->prev);
633 M_COPY(iptr->dst, iptr->dst->prev->prev->prev);
634 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev);
637 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
639 M_COPY(src, iptr->dst);
640 M_COPY(src->prev, iptr->dst->prev);
641 M_COPY(src->prev->prev, iptr->dst->prev->prev);
642 M_COPY(src->prev->prev->prev, iptr->dst->prev->prev->prev);
643 M_COPY(iptr->dst, iptr->dst->prev->prev->prev->prev);
644 M_COPY(iptr->dst->prev, iptr->dst->prev->prev->prev->prev->prev);
647 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
649 M_COPY(src, iptr->dst->prev);
650 M_COPY(src->prev, iptr->dst);
654 /* integer operations *************************************************/
656 case ICMD_INEG: /* ..., value ==> ..., - value */
658 var_to_reg_int(s1, src, REG_ITMP1);
659 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
660 M_ISUB(REG_ZERO, s1, d);
661 store_reg_to_var_int(iptr->dst, d);
664 case ICMD_LNEG: /* ..., value ==> ..., - value */
666 var_to_reg_int(s1, src, REG_ITMP1);
667 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
668 M_LSUB(REG_ZERO, s1, d);
669 store_reg_to_var_int(iptr->dst, d);
672 case ICMD_I2L: /* ..., value ==> ..., value */
674 var_to_reg_int(s1, src, REG_ITMP1);
675 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
677 store_reg_to_var_int(iptr->dst, d);
680 case ICMD_L2I: /* ..., value ==> ..., value */
682 var_to_reg_int(s1, src, REG_ITMP1);
683 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
684 M_IADD(s1, REG_ZERO, d);
685 store_reg_to_var_int(iptr->dst, d);
688 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
690 var_to_reg_int(s1, src, REG_ITMP1);
691 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
692 if (has_ext_instr_set) {
695 M_SLL_IMM(s1, 56, d);
696 M_SRA_IMM( d, 56, d);
698 store_reg_to_var_int(iptr->dst, d);
701 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
703 var_to_reg_int(s1, src, REG_ITMP1);
704 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
706 store_reg_to_var_int(iptr->dst, d);
709 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
711 var_to_reg_int(s1, src, REG_ITMP1);
712 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
713 if (has_ext_instr_set) {
716 M_SLL_IMM(s1, 48, d);
717 M_SRA_IMM( d, 48, d);
719 store_reg_to_var_int(iptr->dst, d);
723 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
725 var_to_reg_int(s1, src->prev, REG_ITMP1);
726 var_to_reg_int(s2, src, REG_ITMP2);
727 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
729 store_reg_to_var_int(iptr->dst, d);
732 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
733 /* val.i = constant */
735 var_to_reg_int(s1, src, REG_ITMP1);
736 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
737 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
738 M_IADD_IMM(s1, iptr->val.i, d);
740 ICONST(REG_ITMP2, iptr->val.i);
741 M_IADD(s1, REG_ITMP2, d);
743 store_reg_to_var_int(iptr->dst, d);
746 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
748 var_to_reg_int(s1, src->prev, REG_ITMP1);
749 var_to_reg_int(s2, src, REG_ITMP2);
750 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
752 store_reg_to_var_int(iptr->dst, d);
755 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
756 /* val.l = constant */
758 var_to_reg_int(s1, src, REG_ITMP1);
759 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
760 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
761 M_LADD_IMM(s1, iptr->val.l, d);
763 LCONST(REG_ITMP2, iptr->val.l);
764 M_LADD(s1, REG_ITMP2, d);
766 store_reg_to_var_int(iptr->dst, d);
769 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
771 var_to_reg_int(s1, src->prev, REG_ITMP1);
772 var_to_reg_int(s2, src, REG_ITMP2);
773 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
775 store_reg_to_var_int(iptr->dst, d);
778 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
779 /* val.i = constant */
781 var_to_reg_int(s1, src, REG_ITMP1);
782 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
783 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
784 M_ISUB_IMM(s1, iptr->val.i, d);
786 ICONST(REG_ITMP2, iptr->val.i);
787 M_ISUB(s1, REG_ITMP2, d);
789 store_reg_to_var_int(iptr->dst, d);
792 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
794 var_to_reg_int(s1, src->prev, REG_ITMP1);
795 var_to_reg_int(s2, src, REG_ITMP2);
796 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
798 store_reg_to_var_int(iptr->dst, d);
801 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
802 /* val.l = constant */
804 var_to_reg_int(s1, src, REG_ITMP1);
805 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
806 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
807 M_LSUB_IMM(s1, iptr->val.l, d);
809 LCONST(REG_ITMP2, iptr->val.l);
810 M_LSUB(s1, REG_ITMP2, d);
812 store_reg_to_var_int(iptr->dst, d);
815 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
817 var_to_reg_int(s1, src->prev, REG_ITMP1);
818 var_to_reg_int(s2, src, REG_ITMP2);
819 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
821 store_reg_to_var_int(iptr->dst, d);
824 case ICMD_IMULCONST: /* ..., value ==> ..., value * constant */
825 /* val.i = constant */
827 var_to_reg_int(s1, src, REG_ITMP1);
828 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
829 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
830 M_IMUL_IMM(s1, iptr->val.i, d);
832 ICONST(REG_ITMP2, iptr->val.i);
833 M_IMUL(s1, REG_ITMP2, d);
835 store_reg_to_var_int(iptr->dst, d);
838 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
840 var_to_reg_int(s1, src->prev, REG_ITMP1);
841 var_to_reg_int(s2, src, REG_ITMP2);
842 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
844 store_reg_to_var_int(iptr->dst, d);
847 case ICMD_LMULCONST: /* ..., value ==> ..., value * constant */
848 /* val.l = constant */
850 var_to_reg_int(s1, src, REG_ITMP1);
851 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
852 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
853 M_LMUL_IMM(s1, iptr->val.l, d);
855 LCONST(REG_ITMP2, iptr->val.l);
856 M_LMUL(s1, REG_ITMP2, d);
858 store_reg_to_var_int(iptr->dst, d);
861 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
862 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
864 var_to_reg_int(s1, src->prev, REG_ITMP1);
865 var_to_reg_int(s2, src, REG_ITMP2);
866 d = reg_of_var(rd, iptr->dst, REG_RESULT);
868 codegen_addxdivrefs(cd, mcodeptr);
870 M_MOV(s1, rd->argintregs[0]);
871 M_MOV(s2, rd->argintregs[1]);
873 disp = dseg_addaddress(cd, bte->fp);
874 M_ALD(REG_PV, REG_PV, disp);
875 M_JSR(REG_RA, REG_PV);
876 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
877 M_LDA(REG_PV, REG_RA, -disp);
879 M_IADD(REG_RESULT, REG_ZERO, d); /* sign extend (bugfix for gcc -O2) */
880 store_reg_to_var_int(iptr->dst, d);
883 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
884 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
886 var_to_reg_int(s1, src->prev, REG_ITMP1);
887 var_to_reg_int(s2, src, REG_ITMP2);
888 d = reg_of_var(rd, iptr->dst, REG_RESULT);
890 codegen_addxdivrefs(cd, mcodeptr);
892 M_MOV(s1, rd->argintregs[0]);
893 M_MOV(s2, rd->argintregs[1]);
895 disp = dseg_addaddress(cd, bte->fp);
896 M_ALD(REG_PV, REG_PV, disp);
897 M_JSR(REG_RA, REG_PV);
898 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
899 M_LDA(REG_PV, REG_RA, -disp);
901 M_INTMOVE(REG_RESULT, d);
902 store_reg_to_var_int(iptr->dst, d);
905 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
906 case ICMD_LDIVPOW2: /* val.i = constant */
908 var_to_reg_int(s1, src, REG_ITMP1);
909 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
910 if (iptr->val.i <= 15) {
911 M_LDA(REG_ITMP2, s1, (1 << iptr->val.i) -1);
912 M_CMOVGE(s1, s1, REG_ITMP2);
914 M_SRA_IMM(s1, 63, REG_ITMP2);
915 M_SRL_IMM(REG_ITMP2, 64 - iptr->val.i, REG_ITMP2);
916 M_LADD(s1, REG_ITMP2, REG_ITMP2);
918 M_SRA_IMM(REG_ITMP2, iptr->val.i, d);
919 store_reg_to_var_int(iptr->dst, d);
922 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
924 var_to_reg_int(s1, src->prev, REG_ITMP1);
925 var_to_reg_int(s2, src, REG_ITMP2);
926 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
927 M_AND_IMM(s2, 0x1f, REG_ITMP3);
928 M_SLL(s1, REG_ITMP3, d);
929 M_IADD(d, REG_ZERO, d);
930 store_reg_to_var_int(iptr->dst, d);
933 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
934 /* val.i = constant */
936 var_to_reg_int(s1, src, REG_ITMP1);
937 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
938 M_SLL_IMM(s1, iptr->val.i & 0x1f, d);
939 M_IADD(d, REG_ZERO, d);
940 store_reg_to_var_int(iptr->dst, d);
943 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
945 var_to_reg_int(s1, src->prev, REG_ITMP1);
946 var_to_reg_int(s2, src, REG_ITMP2);
947 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
948 M_AND_IMM(s2, 0x1f, REG_ITMP3);
949 M_SRA(s1, REG_ITMP3, d);
950 store_reg_to_var_int(iptr->dst, d);
953 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
954 /* val.i = constant */
956 var_to_reg_int(s1, src, REG_ITMP1);
957 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
958 M_SRA_IMM(s1, iptr->val.i & 0x1f, d);
959 store_reg_to_var_int(iptr->dst, d);
962 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
964 var_to_reg_int(s1, src->prev, REG_ITMP1);
965 var_to_reg_int(s2, src, REG_ITMP2);
966 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
967 M_AND_IMM(s2, 0x1f, REG_ITMP2);
969 M_SRL(d, REG_ITMP2, d);
970 M_IADD(d, REG_ZERO, d);
971 store_reg_to_var_int(iptr->dst, d);
974 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
975 /* val.i = constant */
977 var_to_reg_int(s1, src, REG_ITMP1);
978 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
980 M_SRL_IMM(d, iptr->val.i & 0x1f, d);
981 M_IADD(d, REG_ZERO, d);
982 store_reg_to_var_int(iptr->dst, d);
985 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
987 var_to_reg_int(s1, src->prev, REG_ITMP1);
988 var_to_reg_int(s2, src, REG_ITMP2);
989 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
991 store_reg_to_var_int(iptr->dst, d);
994 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
995 /* val.i = constant */
997 var_to_reg_int(s1, src, REG_ITMP1);
998 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
999 M_SLL_IMM(s1, iptr->val.i & 0x3f, d);
1000 store_reg_to_var_int(iptr->dst, d);
1003 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
1005 var_to_reg_int(s1, src->prev, REG_ITMP1);
1006 var_to_reg_int(s2, src, REG_ITMP2);
1007 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1009 store_reg_to_var_int(iptr->dst, d);
1012 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
1013 /* val.i = constant */
1015 var_to_reg_int(s1, src, REG_ITMP1);
1016 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1017 M_SRA_IMM(s1, iptr->val.i & 0x3f, d);
1018 store_reg_to_var_int(iptr->dst, d);
1021 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
1023 var_to_reg_int(s1, src->prev, REG_ITMP1);
1024 var_to_reg_int(s2, src, REG_ITMP2);
1025 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1027 store_reg_to_var_int(iptr->dst, d);
1030 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
1031 /* val.i = constant */
1033 var_to_reg_int(s1, src, REG_ITMP1);
1034 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1035 M_SRL_IMM(s1, iptr->val.i & 0x3f, d);
1036 store_reg_to_var_int(iptr->dst, d);
1039 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
1042 var_to_reg_int(s1, src->prev, REG_ITMP1);
1043 var_to_reg_int(s2, src, REG_ITMP2);
1044 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1046 store_reg_to_var_int(iptr->dst, d);
1049 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
1050 /* val.i = constant */
1052 var_to_reg_int(s1, src, REG_ITMP1);
1053 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1054 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1055 M_AND_IMM(s1, iptr->val.i, d);
1056 } else if (iptr->val.i == 0xffff) {
1058 } else if (iptr->val.i == 0xffffff) {
1059 M_ZAPNOT_IMM(s1, 0x07, d);
1061 ICONST(REG_ITMP2, iptr->val.i);
1062 M_AND(s1, REG_ITMP2, d);
1064 store_reg_to_var_int(iptr->dst, d);
1067 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
1068 /* val.i = constant */
1070 var_to_reg_int(s1, src, REG_ITMP1);
1071 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1073 M_MOV(s1, REG_ITMP1);
1076 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1077 M_AND_IMM(s1, iptr->val.i, d);
1079 M_ISUB(REG_ZERO, s1, d);
1080 M_AND_IMM(d, iptr->val.i, d);
1081 } else if (iptr->val.i == 0xffff) {
1084 M_ISUB(REG_ZERO, s1, d);
1086 } else if (iptr->val.i == 0xffffff) {
1087 M_ZAPNOT_IMM(s1, 0x07, d);
1089 M_ISUB(REG_ZERO, s1, d);
1090 M_ZAPNOT_IMM(d, 0x07, d);
1092 ICONST(REG_ITMP2, iptr->val.i);
1093 M_AND(s1, REG_ITMP2, d);
1095 M_ISUB(REG_ZERO, s1, d);
1096 M_AND(d, REG_ITMP2, d);
1098 M_ISUB(REG_ZERO, d, d);
1099 store_reg_to_var_int(iptr->dst, d);
1102 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
1103 /* val.l = constant */
1105 var_to_reg_int(s1, src, REG_ITMP1);
1106 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1107 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1108 M_AND_IMM(s1, iptr->val.l, d);
1109 } else if (iptr->val.l == 0xffffL) {
1111 } else if (iptr->val.l == 0xffffffL) {
1112 M_ZAPNOT_IMM(s1, 0x07, d);
1113 } else if (iptr->val.l == 0xffffffffL) {
1115 } else if (iptr->val.l == 0xffffffffffL) {
1116 M_ZAPNOT_IMM(s1, 0x1f, d);
1117 } else if (iptr->val.l == 0xffffffffffffL) {
1118 M_ZAPNOT_IMM(s1, 0x3f, d);
1119 } else if (iptr->val.l == 0xffffffffffffffL) {
1120 M_ZAPNOT_IMM(s1, 0x7f, d);
1122 LCONST(REG_ITMP2, iptr->val.l);
1123 M_AND(s1, REG_ITMP2, d);
1125 store_reg_to_var_int(iptr->dst, d);
1128 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
1129 /* val.l = constant */
1131 var_to_reg_int(s1, src, REG_ITMP1);
1132 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1134 M_MOV(s1, REG_ITMP1);
1137 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1138 M_AND_IMM(s1, iptr->val.l, d);
1140 M_LSUB(REG_ZERO, s1, d);
1141 M_AND_IMM(d, iptr->val.l, d);
1142 } else if (iptr->val.l == 0xffffL) {
1145 M_LSUB(REG_ZERO, s1, d);
1147 } else if (iptr->val.l == 0xffffffL) {
1148 M_ZAPNOT_IMM(s1, 0x07, d);
1150 M_LSUB(REG_ZERO, s1, d);
1151 M_ZAPNOT_IMM(d, 0x07, d);
1152 } else if (iptr->val.l == 0xffffffffL) {
1155 M_LSUB(REG_ZERO, s1, d);
1157 } else if (iptr->val.l == 0xffffffffffL) {
1158 M_ZAPNOT_IMM(s1, 0x1f, d);
1160 M_LSUB(REG_ZERO, s1, d);
1161 M_ZAPNOT_IMM(d, 0x1f, d);
1162 } else if (iptr->val.l == 0xffffffffffffL) {
1163 M_ZAPNOT_IMM(s1, 0x3f, d);
1165 M_LSUB(REG_ZERO, s1, d);
1166 M_ZAPNOT_IMM(d, 0x3f, d);
1167 } else if (iptr->val.l == 0xffffffffffffffL) {
1168 M_ZAPNOT_IMM(s1, 0x7f, d);
1170 M_LSUB(REG_ZERO, s1, d);
1171 M_ZAPNOT_IMM(d, 0x7f, d);
1173 LCONST(REG_ITMP2, iptr->val.l);
1174 M_AND(s1, REG_ITMP2, d);
1176 M_LSUB(REG_ZERO, s1, d);
1177 M_AND(d, REG_ITMP2, d);
1179 M_LSUB(REG_ZERO, d, d);
1180 store_reg_to_var_int(iptr->dst, d);
1183 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
1186 var_to_reg_int(s1, src->prev, REG_ITMP1);
1187 var_to_reg_int(s2, src, REG_ITMP2);
1188 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1190 store_reg_to_var_int(iptr->dst, d);
1193 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
1194 /* val.i = constant */
1196 var_to_reg_int(s1, src, REG_ITMP1);
1197 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1198 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1199 M_OR_IMM(s1, iptr->val.i, d);
1201 ICONST(REG_ITMP2, iptr->val.i);
1202 M_OR(s1, REG_ITMP2, d);
1204 store_reg_to_var_int(iptr->dst, d);
1207 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
1208 /* val.l = constant */
1210 var_to_reg_int(s1, src, REG_ITMP1);
1211 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1212 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1213 M_OR_IMM(s1, iptr->val.l, d);
1215 LCONST(REG_ITMP2, iptr->val.l);
1216 M_OR(s1, REG_ITMP2, d);
1218 store_reg_to_var_int(iptr->dst, d);
1221 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
1224 var_to_reg_int(s1, src->prev, REG_ITMP1);
1225 var_to_reg_int(s2, src, REG_ITMP2);
1226 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1228 store_reg_to_var_int(iptr->dst, d);
1231 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
1232 /* val.i = constant */
1234 var_to_reg_int(s1, src, REG_ITMP1);
1235 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1236 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1237 M_XOR_IMM(s1, iptr->val.i, d);
1239 ICONST(REG_ITMP2, iptr->val.i);
1240 M_XOR(s1, REG_ITMP2, d);
1242 store_reg_to_var_int(iptr->dst, d);
1245 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
1246 /* val.l = constant */
1248 var_to_reg_int(s1, src, REG_ITMP1);
1249 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1250 if ((iptr->val.l >= 0) && (iptr->val.l <= 255)) {
1251 M_XOR_IMM(s1, iptr->val.l, d);
1253 LCONST(REG_ITMP2, iptr->val.l);
1254 M_XOR(s1, REG_ITMP2, d);
1256 store_reg_to_var_int(iptr->dst, d);
1260 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
1262 var_to_reg_int(s1, src->prev, REG_ITMP1);
1263 var_to_reg_int(s2, src, REG_ITMP2);
1264 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1265 M_CMPLT(s1, s2, REG_ITMP3);
1266 M_CMPLT(s2, s1, REG_ITMP1);
1267 M_LSUB(REG_ITMP1, REG_ITMP3, d);
1268 store_reg_to_var_int(iptr->dst, d);
1272 case ICMD_IINC: /* ..., value ==> ..., value + constant */
1273 /* op1 = variable, val.i = constant */
1275 var = &(rd->locals[iptr->op1][TYPE_INT]);
1276 if (var->flags & INMEMORY) {
1278 M_LLD(s1, REG_SP, var->regoff * 8);
1281 if ((iptr->val.i >= 0) && (iptr->val.i <= 255)) {
1282 M_IADD_IMM(s1, iptr->val.i, s1);
1283 } else if ((iptr->val.i > -256) && (iptr->val.i < 0)) {
1284 M_ISUB_IMM(s1, (-iptr->val.i), s1);
1286 M_LDA (s1, s1, iptr->val.i);
1287 M_IADD(s1, REG_ZERO, s1);
1289 if (var->flags & INMEMORY)
1290 M_LST(s1, REG_SP, var->regoff * 8);
1294 /* floating operations ************************************************/
1296 case ICMD_FNEG: /* ..., value ==> ..., - value */
1298 var_to_reg_flt(s1, src, REG_FTMP1);
1299 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1301 store_reg_to_var_flt(iptr->dst, d);
1304 case ICMD_DNEG: /* ..., value ==> ..., - value */
1306 var_to_reg_flt(s1, src, REG_FTMP1);
1307 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1309 store_reg_to_var_flt(iptr->dst, d);
1312 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1314 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1315 var_to_reg_flt(s2, src, REG_FTMP2);
1316 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1320 if (d == s1 || d == s2) {
1321 M_FADDS(s1, s2, REG_FTMP3);
1323 M_FMOV(REG_FTMP3, d);
1329 store_reg_to_var_flt(iptr->dst, d);
1332 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
1334 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1335 var_to_reg_flt(s2, src, REG_FTMP2);
1336 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1340 if (d == s1 || d == s2) {
1341 M_DADDS(s1, s2, REG_FTMP3);
1343 M_FMOV(REG_FTMP3, d);
1349 store_reg_to_var_flt(iptr->dst, d);
1352 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1354 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1355 var_to_reg_flt(s2, src, REG_FTMP2);
1356 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1360 if (d == s1 || d == s2) {
1361 M_FSUBS(s1, s2, REG_FTMP3);
1363 M_FMOV(REG_FTMP3, d);
1369 store_reg_to_var_flt(iptr->dst, d);
1372 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
1374 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1375 var_to_reg_flt(s2, src, REG_FTMP2);
1376 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1380 if (d == s1 || d == s2) {
1381 M_DSUBS(s1, s2, REG_FTMP3);
1383 M_FMOV(REG_FTMP3, d);
1389 store_reg_to_var_flt(iptr->dst, d);
1392 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
1394 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1395 var_to_reg_flt(s2, src, REG_FTMP2);
1396 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1400 if (d == s1 || d == s2) {
1401 M_FMULS(s1, s2, REG_FTMP3);
1403 M_FMOV(REG_FTMP3, d);
1409 store_reg_to_var_flt(iptr->dst, d);
1412 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
1414 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1415 var_to_reg_flt(s2, src, REG_FTMP2);
1416 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1420 if (d == s1 || d == s2) {
1421 M_DMULS(s1, s2, REG_FTMP3);
1423 M_FMOV(REG_FTMP3, d);
1429 store_reg_to_var_flt(iptr->dst, d);
1432 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1434 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1435 var_to_reg_flt(s2, src, REG_FTMP2);
1436 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1440 if (d == s1 || d == s2) {
1441 M_FDIVS(s1, s2, REG_FTMP3);
1443 M_FMOV(REG_FTMP3, d);
1449 store_reg_to_var_flt(iptr->dst, d);
1452 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
1454 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1455 var_to_reg_flt(s2, src, REG_FTMP2);
1456 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1460 if (d == s1 || d == s2) {
1461 M_DDIVS(s1, s2, REG_FTMP3);
1463 M_FMOV(REG_FTMP3, d);
1469 store_reg_to_var_flt(iptr->dst, d);
1472 case ICMD_I2F: /* ..., value ==> ..., (float) value */
1474 var_to_reg_int(s1, src, REG_ITMP1);
1475 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1476 disp = dseg_adddouble(cd, 0.0);
1477 M_LST(s1, REG_PV, disp);
1478 M_DLD(d, REG_PV, disp);
1480 store_reg_to_var_flt(iptr->dst, d);
1483 case ICMD_I2D: /* ..., value ==> ..., (double) value */
1485 var_to_reg_int(s1, src, REG_ITMP1);
1486 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1487 disp = dseg_adddouble(cd, 0.0);
1488 M_LST(s1, REG_PV, disp);
1489 M_DLD(d, REG_PV, disp);
1491 store_reg_to_var_flt(iptr->dst, d);
1494 case ICMD_F2I: /* ..., value ==> ..., (int) value */
1496 var_to_reg_flt(s1, src, REG_FTMP1);
1497 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1498 disp = dseg_adddouble(cd, 0.0);
1499 M_CVTDL_C(s1, REG_FTMP2);
1500 M_CVTLI(REG_FTMP2, REG_FTMP3);
1501 M_DST(REG_FTMP3, REG_PV, disp);
1502 M_ILD(d, REG_PV, disp);
1503 store_reg_to_var_int(iptr->dst, d);
1506 case ICMD_F2L: /* ..., value ==> ..., (long) value */
1508 var_to_reg_flt(s1, src, REG_FTMP1);
1509 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1510 disp = dseg_adddouble(cd, 0.0);
1511 M_CVTDL_C(s1, REG_FTMP2);
1512 M_DST(REG_FTMP2, REG_PV, disp);
1513 M_LLD(d, REG_PV, disp);
1514 store_reg_to_var_int(iptr->dst, d);
1517 case ICMD_F2D: /* ..., value ==> ..., (double) value */
1519 var_to_reg_flt(s1, src, REG_FTMP1);
1520 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1523 store_reg_to_var_flt(iptr->dst, d);
1526 case ICMD_D2F: /* ..., value ==> ..., (float) value */
1528 var_to_reg_flt(s1, src, REG_FTMP1);
1529 d = reg_of_var(rd, iptr->dst, REG_FTMP3);
1536 store_reg_to_var_flt(iptr->dst, d);
1539 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
1541 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1542 var_to_reg_flt(s2, src, REG_FTMP2);
1543 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1545 M_LSUB_IMM(REG_ZERO, 1, d);
1546 M_FCMPEQ(s1, s2, REG_FTMP3);
1547 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1549 M_FCMPLT(s2, s1, REG_FTMP3);
1550 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1551 M_LADD_IMM(REG_ZERO, 1, d);
1553 M_LSUB_IMM(REG_ZERO, 1, d);
1554 M_FCMPEQS(s1, s2, REG_FTMP3);
1556 M_FBEQZ (REG_FTMP3, 1); /* jump over next instructions */
1558 M_FCMPLTS(s2, s1, REG_FTMP3);
1560 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1561 M_LADD_IMM(REG_ZERO, 1, d);
1563 store_reg_to_var_int(iptr->dst, d);
1566 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
1568 var_to_reg_flt(s1, src->prev, REG_FTMP1);
1569 var_to_reg_flt(s2, src, REG_FTMP2);
1570 d = reg_of_var(rd, iptr->dst, REG_ITMP3);
1572 M_LADD_IMM(REG_ZERO, 1, d);
1573 M_FCMPEQ(s1, s2, REG_FTMP3);
1574 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1576 M_FCMPLT(s1, s2, REG_FTMP3);
1577 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1578 M_LSUB_IMM(REG_ZERO, 1, d);
1580 M_LADD_IMM(REG_ZERO, 1, d);
1581 M_FCMPEQS(s1, s2, REG_FTMP3);
1583 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1585 M_FCMPLTS(s1, s2, REG_FTMP3);
1587 M_FBEQZ (REG_FTMP3, 1); /* jump over next instruction */
1588 M_LSUB_IMM(REG_ZERO, 1, d);
1590 store_reg_to_var_int(iptr->dst, d);
1594 /* memory operations **************************************************/
1596 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
1598 var_to_reg_int(s1, src, REG_ITMP1);
1599 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1600 gen_nullptr_check(s1);
1601 M_ILD(d, s1, OFFSET(java_arrayheader, size));
1602 store_reg_to_var_int(iptr->dst, d);
1605 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
1607 var_to_reg_int(s1, src->prev, REG_ITMP1);
1608 var_to_reg_int(s2, src, REG_ITMP2);
1609 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1610 if (iptr->op1 == 0) {
1611 gen_nullptr_check(s1);
1614 if (has_ext_instr_set) {
1615 M_LADD (s2, s1, REG_ITMP1);
1616 M_BLDU (d, REG_ITMP1, OFFSET (java_bytearray, data[0]));
1619 M_LADD(s2, s1, REG_ITMP1);
1620 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1621 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0])+1);
1622 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1623 M_SRA_IMM(d, 56, d);
1625 store_reg_to_var_int(iptr->dst, d);
1628 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1630 var_to_reg_int(s1, src->prev, REG_ITMP1);
1631 var_to_reg_int(s2, src, REG_ITMP2);
1632 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1633 if (iptr->op1 == 0) {
1634 gen_nullptr_check(s1);
1637 if (has_ext_instr_set) {
1638 M_LADD(s2, s1, REG_ITMP1);
1639 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1640 M_SLDU(d, REG_ITMP1, OFFSET(java_chararray, data[0]));
1642 M_LADD (s2, s1, REG_ITMP1);
1643 M_LADD (s2, REG_ITMP1, REG_ITMP1);
1644 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1645 M_LDA (REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1646 M_EXTWL(REG_ITMP2, REG_ITMP1, d);
1648 store_reg_to_var_int(iptr->dst, d);
1651 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1653 var_to_reg_int(s1, src->prev, REG_ITMP1);
1654 var_to_reg_int(s2, src, REG_ITMP2);
1655 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1656 if (iptr->op1 == 0) {
1657 gen_nullptr_check(s1);
1660 if (has_ext_instr_set) {
1661 M_LADD(s2, s1, REG_ITMP1);
1662 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1663 M_SLDU( d, REG_ITMP1, OFFSET (java_shortarray, data[0]));
1666 M_LADD(s2, s1, REG_ITMP1);
1667 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1668 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1669 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0])+2);
1670 M_EXTQH(REG_ITMP2, REG_ITMP1, d);
1671 M_SRA_IMM(d, 48, d);
1673 store_reg_to_var_int(iptr->dst, d);
1676 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1678 var_to_reg_int(s1, src->prev, REG_ITMP1);
1679 var_to_reg_int(s2, src, REG_ITMP2);
1680 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1681 if (iptr->op1 == 0) {
1682 gen_nullptr_check(s1);
1685 M_S4ADDQ(s2, s1, REG_ITMP1);
1686 M_ILD(d, REG_ITMP1, OFFSET(java_intarray, data[0]));
1687 store_reg_to_var_int(iptr->dst, d);
1690 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1692 var_to_reg_int(s1, src->prev, REG_ITMP1);
1693 var_to_reg_int(s2, src, REG_ITMP2);
1694 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1695 if (iptr->op1 == 0) {
1696 gen_nullptr_check(s1);
1699 M_S8ADDQ(s2, s1, REG_ITMP1);
1700 M_LLD(d, REG_ITMP1, OFFSET(java_longarray, data[0]));
1701 store_reg_to_var_int(iptr->dst, d);
1704 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1706 var_to_reg_int(s1, src->prev, REG_ITMP1);
1707 var_to_reg_int(s2, src, REG_ITMP2);
1708 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1709 if (iptr->op1 == 0) {
1710 gen_nullptr_check(s1);
1713 M_S4ADDQ(s2, s1, REG_ITMP1);
1714 M_FLD(d, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1715 store_reg_to_var_flt(iptr->dst, d);
1718 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1720 var_to_reg_int(s1, src->prev, REG_ITMP1);
1721 var_to_reg_int(s2, src, REG_ITMP2);
1722 d = reg_of_var(rd, iptr->dst, REG_FTMP2);
1723 if (iptr->op1 == 0) {
1724 gen_nullptr_check(s1);
1727 M_S8ADDQ(s2, s1, REG_ITMP1);
1728 M_DLD(d, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1729 store_reg_to_var_flt(iptr->dst, d);
1732 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1734 var_to_reg_int(s1, src->prev, REG_ITMP1);
1735 var_to_reg_int(s2, src, REG_ITMP2);
1736 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
1737 if (iptr->op1 == 0) {
1738 gen_nullptr_check(s1);
1741 M_SAADDQ(s2, s1, REG_ITMP1);
1742 M_ALD(d, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1743 store_reg_to_var_int(iptr->dst, d);
1747 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1749 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1750 var_to_reg_int(s2, src->prev, REG_ITMP2);
1751 if (iptr->op1 == 0) {
1752 gen_nullptr_check(s1);
1755 var_to_reg_int(s3, src, REG_ITMP3);
1756 if (has_ext_instr_set) {
1757 M_LADD(s2, s1, REG_ITMP1);
1758 M_BST(s3, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1760 M_LADD(s2, s1, REG_ITMP1);
1761 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1762 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1763 M_INSBL(s3, REG_ITMP1, REG_ITMP3);
1764 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1765 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1766 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1770 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1772 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1773 var_to_reg_int(s2, src->prev, REG_ITMP2);
1774 if (iptr->op1 == 0) {
1775 gen_nullptr_check(s1);
1778 var_to_reg_int(s3, src, REG_ITMP3);
1779 if (has_ext_instr_set) {
1780 M_LADD(s2, s1, REG_ITMP1);
1781 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1782 M_SST(s3, REG_ITMP1, OFFSET(java_chararray, data[0]));
1784 M_LADD(s2, s1, REG_ITMP1);
1785 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1786 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1787 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1788 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1789 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1790 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1791 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1795 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1797 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1798 var_to_reg_int(s2, src->prev, REG_ITMP2);
1799 if (iptr->op1 == 0) {
1800 gen_nullptr_check(s1);
1803 var_to_reg_int(s3, src, REG_ITMP3);
1804 if (has_ext_instr_set) {
1805 M_LADD(s2, s1, REG_ITMP1);
1806 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1807 M_SST(s3, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1809 M_LADD(s2, s1, REG_ITMP1);
1810 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1811 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1812 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1813 M_INSWL(s3, REG_ITMP1, REG_ITMP3);
1814 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1815 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1816 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1820 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1822 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1823 var_to_reg_int(s2, src->prev, REG_ITMP2);
1824 if (iptr->op1 == 0) {
1825 gen_nullptr_check(s1);
1828 var_to_reg_int(s3, src, REG_ITMP3);
1829 M_S4ADDQ(s2, s1, REG_ITMP1);
1830 M_IST(s3, REG_ITMP1, OFFSET(java_intarray, data[0]));
1833 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1835 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1836 var_to_reg_int(s2, src->prev, REG_ITMP2);
1837 if (iptr->op1 == 0) {
1838 gen_nullptr_check(s1);
1841 var_to_reg_int(s3, src, REG_ITMP3);
1842 M_S8ADDQ(s2, s1, REG_ITMP1);
1843 M_LST(s3, REG_ITMP1, OFFSET(java_longarray, data[0]));
1846 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1848 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1849 var_to_reg_int(s2, src->prev, REG_ITMP2);
1850 if (iptr->op1 == 0) {
1851 gen_nullptr_check(s1);
1854 var_to_reg_flt(s3, src, REG_FTMP3);
1855 M_S4ADDQ(s2, s1, REG_ITMP1);
1856 M_FST(s3, REG_ITMP1, OFFSET(java_floatarray, data[0]));
1859 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1861 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1862 var_to_reg_int(s2, src->prev, REG_ITMP2);
1863 if (iptr->op1 == 0) {
1864 gen_nullptr_check(s1);
1867 var_to_reg_flt(s3, src, REG_FTMP3);
1868 M_S8ADDQ(s2, s1, REG_ITMP1);
1869 M_DST(s3, REG_ITMP1, OFFSET(java_doublearray, data[0]));
1872 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1874 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1875 var_to_reg_int(s2, src->prev, REG_ITMP2);
1876 if (iptr->op1 == 0) {
1877 gen_nullptr_check(s1);
1880 var_to_reg_int(s3, src, REG_ITMP3);
1882 M_MOV(s1, rd->argintregs[0]);
1883 M_MOV(s3, rd->argintregs[1]);
1884 disp = dseg_addaddress(cd, BUILTIN_canstore);
1885 M_ALD(REG_PV, REG_PV, disp);
1886 M_JSR(REG_RA, REG_PV);
1887 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
1888 M_LDA(REG_PV, REG_RA, -disp);
1890 M_BEQZ(REG_RESULT, 0);
1891 codegen_addxstorerefs(cd, mcodeptr);
1893 var_to_reg_int(s1, src->prev->prev, REG_ITMP1);
1894 var_to_reg_int(s2, src->prev, REG_ITMP2);
1895 var_to_reg_int(s3, src, REG_ITMP3);
1896 M_SAADDQ(s2, s1, REG_ITMP1);
1897 M_AST(s3, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1901 case ICMD_IASTORECONST: /* ..., arrayref, index ==> ... */
1903 var_to_reg_int(s1, src->prev, REG_ITMP1);
1904 var_to_reg_int(s2, src, REG_ITMP2);
1905 if (iptr->op1 == 0) {
1906 gen_nullptr_check(s1);
1909 M_S4ADDQ(s2, s1, REG_ITMP1);
1910 M_IST(REG_ZERO, REG_ITMP1, OFFSET(java_intarray, data[0]));
1913 case ICMD_LASTORECONST: /* ..., arrayref, index ==> ... */
1915 var_to_reg_int(s1, src->prev, REG_ITMP1);
1916 var_to_reg_int(s2, src, REG_ITMP2);
1917 if (iptr->op1 == 0) {
1918 gen_nullptr_check(s1);
1921 M_S8ADDQ(s2, s1, REG_ITMP1);
1922 M_LST(REG_ZERO, REG_ITMP1, OFFSET(java_longarray, data[0]));
1925 case ICMD_AASTORECONST: /* ..., arrayref, index ==> ... */
1927 var_to_reg_int(s1, src->prev, REG_ITMP1);
1928 var_to_reg_int(s2, src, REG_ITMP2);
1929 if (iptr->op1 == 0) {
1930 gen_nullptr_check(s1);
1933 M_SAADDQ(s2, s1, REG_ITMP1);
1934 M_AST(REG_ZERO, REG_ITMP1, OFFSET(java_objectarray, data[0]));
1937 case ICMD_BASTORECONST: /* ..., arrayref, index ==> ... */
1939 var_to_reg_int(s1, src->prev, REG_ITMP1);
1940 var_to_reg_int(s2, src, REG_ITMP2);
1941 if (iptr->op1 == 0) {
1942 gen_nullptr_check(s1);
1945 if (has_ext_instr_set) {
1946 M_LADD(s2, s1, REG_ITMP1);
1947 M_BST(REG_ZERO, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1950 M_LADD(s2, s1, REG_ITMP1);
1951 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1952 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_bytearray, data[0]));
1953 M_INSBL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1954 M_MSKBL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1955 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1956 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1960 case ICMD_CASTORECONST: /* ..., arrayref, index ==> ... */
1962 var_to_reg_int(s1, src->prev, REG_ITMP1);
1963 var_to_reg_int(s2, src, REG_ITMP2);
1964 if (iptr->op1 == 0) {
1965 gen_nullptr_check(s1);
1968 if (has_ext_instr_set) {
1969 M_LADD(s2, s1, REG_ITMP1);
1970 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1971 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_chararray, data[0]));
1974 M_LADD(s2, s1, REG_ITMP1);
1975 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1976 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_chararray, data[0]));
1977 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_chararray, data[0]));
1978 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
1979 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
1980 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
1981 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
1985 case ICMD_SASTORECONST: /* ..., arrayref, index ==> ... */
1987 var_to_reg_int(s1, src->prev, REG_ITMP1);
1988 var_to_reg_int(s2, src, REG_ITMP2);
1989 if (iptr->op1 == 0) {
1990 gen_nullptr_check(s1);
1993 if (has_ext_instr_set) {
1994 M_LADD(s2, s1, REG_ITMP1);
1995 M_LADD(s2, REG_ITMP1, REG_ITMP1);
1996 M_SST(REG_ZERO, REG_ITMP1, OFFSET(java_shortarray, data[0]));
1999 M_LADD(s2, s1, REG_ITMP1);
2000 M_LADD(s2, REG_ITMP1, REG_ITMP1);
2001 M_LLD_U(REG_ITMP2, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2002 M_LDA(REG_ITMP1, REG_ITMP1, OFFSET(java_shortarray, data[0]));
2003 M_INSWL(REG_ZERO, REG_ITMP1, REG_ITMP3);
2004 M_MSKWL(REG_ITMP2, REG_ITMP1, REG_ITMP2);
2005 M_OR(REG_ITMP2, REG_ITMP3, REG_ITMP2);
2006 M_LST_U(REG_ITMP2, REG_ITMP1, 0);
2011 case ICMD_GETSTATIC: /* ... ==> ..., value */
2012 /* op1 = type, val.a = field address */
2014 if (iptr->val.a == NULL) {
2015 disp = dseg_addaddress(cd, 0);
2017 codegen_addpatchref(cd, mcodeptr,
2018 PATCHER_get_putstatic,
2019 (unresolved_field *) iptr->target, disp);
2021 if (opt_showdisassemble)
2026 fieldinfo *fi = iptr->val.a;
2028 disp = dseg_addaddress(cd, &(fi->value));
2030 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2031 codegen_addpatchref(cd, mcodeptr,
2032 PATCHER_clinit, fi->class, 0);
2034 if (opt_showdisassemble)
2039 M_ALD(REG_ITMP1, REG_PV, disp);
2040 switch (iptr->op1) {
2042 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2043 M_ILD(d, REG_ITMP1, 0);
2044 store_reg_to_var_int(iptr->dst, d);
2047 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2048 M_LLD(d, REG_ITMP1, 0);
2049 store_reg_to_var_int(iptr->dst, d);
2052 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2053 M_ALD(d, REG_ITMP1, 0);
2054 store_reg_to_var_int(iptr->dst, d);
2057 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2058 M_FLD(d, REG_ITMP1, 0);
2059 store_reg_to_var_flt(iptr->dst, d);
2062 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2063 M_DLD(d, REG_ITMP1, 0);
2064 store_reg_to_var_flt(iptr->dst, d);
2069 case ICMD_PUTSTATIC: /* ..., value ==> ... */
2070 /* op1 = type, val.a = field address */
2072 if (iptr->val.a == NULL) {
2073 disp = dseg_addaddress(cd, 0);
2075 codegen_addpatchref(cd, mcodeptr,
2076 PATCHER_get_putstatic,
2077 (unresolved_field *) iptr->target, disp);
2079 if (opt_showdisassemble)
2083 fieldinfo *fi = iptr->val.a;
2085 disp = dseg_addaddress(cd, &(fi->value));
2087 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2088 codegen_addpatchref(cd, mcodeptr,
2089 PATCHER_clinit, fi->class, 0);
2091 if (opt_showdisassemble)
2096 M_ALD(REG_ITMP1, REG_PV, disp);
2097 switch (iptr->op1) {
2099 var_to_reg_int(s2, src, REG_ITMP2);
2100 M_IST(s2, REG_ITMP1, 0);
2103 var_to_reg_int(s2, src, REG_ITMP2);
2104 M_LST(s2, REG_ITMP1, 0);
2107 var_to_reg_int(s2, src, REG_ITMP2);
2108 M_AST(s2, REG_ITMP1, 0);
2111 var_to_reg_flt(s2, src, REG_FTMP2);
2112 M_FST(s2, REG_ITMP1, 0);
2115 var_to_reg_flt(s2, src, REG_FTMP2);
2116 M_DST(s2, REG_ITMP1, 0);
2121 case ICMD_PUTSTATICCONST: /* ... ==> ... */
2122 /* val = value (in current instruction) */
2123 /* op1 = type, val.a = field address (in */
2124 /* following NOP) */
2126 if (iptr[1].val.a == NULL) {
2127 disp = dseg_addaddress(cd, 0);
2129 codegen_addpatchref(cd, mcodeptr,
2130 PATCHER_get_putstatic,
2131 (unresolved_field *) iptr[1].target, disp);
2133 if (opt_showdisassemble)
2137 fieldinfo *fi = iptr[1].val.a;
2139 disp = dseg_addaddress(cd, &(fi->value));
2141 if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
2142 codegen_addpatchref(cd, mcodeptr,
2143 PATCHER_clinit, fi->class, 0);
2145 if (opt_showdisassemble)
2150 M_ALD(REG_ITMP1, REG_PV, disp);
2151 switch (iptr->op1) {
2153 M_IST(REG_ZERO, REG_ITMP1, 0);
2156 M_LST(REG_ZERO, REG_ITMP1, 0);
2159 M_AST(REG_ZERO, REG_ITMP1, 0);
2162 M_FST(REG_ZERO, REG_ITMP1, 0);
2165 M_DST(REG_ZERO, REG_ITMP1, 0);
2171 case ICMD_GETFIELD: /* ... ==> ..., value */
2172 /* op1 = type, val.i = field offset */
2174 var_to_reg_int(s1, src, REG_ITMP1);
2175 gen_nullptr_check(s1);
2177 if (iptr->val.a == NULL) {
2178 codegen_addpatchref(cd, mcodeptr,
2179 PATCHER_get_putfield,
2180 (unresolved_field *) iptr->target, 0);
2182 if (opt_showdisassemble)
2188 disp = ((fieldinfo *) (iptr->val.a))->offset;
2191 switch (iptr->op1) {
2193 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2195 store_reg_to_var_int(iptr->dst, d);
2198 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2200 store_reg_to_var_int(iptr->dst, d);
2203 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2205 store_reg_to_var_int(iptr->dst, d);
2208 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2210 store_reg_to_var_flt(iptr->dst, d);
2213 d = reg_of_var(rd, iptr->dst, REG_FTMP1);
2215 store_reg_to_var_flt(iptr->dst, d);
2220 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
2221 /* op1 = type, val.a = field address */
2223 var_to_reg_int(s1, src->prev, REG_ITMP1);
2224 gen_nullptr_check(s1);
2226 if (!IS_FLT_DBL_TYPE(iptr->op1)) {
2227 var_to_reg_int(s2, src, REG_ITMP2);
2229 var_to_reg_flt(s2, src, REG_FTMP2);
2232 if (iptr->val.a == NULL) {
2233 codegen_addpatchref(cd, mcodeptr,
2234 PATCHER_get_putfield,
2235 (unresolved_field *) iptr->target, 0);
2237 if (opt_showdisassemble)
2243 disp = ((fieldinfo *) (iptr->val.a))->offset;
2246 switch (iptr->op1) {
2248 M_IST(s2, s1, disp);
2251 M_LST(s2, s1, disp);
2254 M_AST(s2, s1, disp);
2257 M_FST(s2, s1, disp);
2260 M_DST(s2, s1, disp);
2265 case ICMD_PUTFIELDCONST: /* ..., objectref ==> ... */
2266 /* val = value (in current instruction) */
2267 /* op1 = type, val.a = field address (in */
2268 /* following NOP) */
2270 var_to_reg_int(s1, src, REG_ITMP1);
2271 gen_nullptr_check(s1);
2273 if (iptr[1].val.a == NULL) {
2274 codegen_addpatchref(cd, mcodeptr,
2275 PATCHER_get_putfield,
2276 (unresolved_field *) iptr[1].target, 0);
2278 if (opt_showdisassemble)
2284 disp = ((fieldinfo *) (iptr[1].val.a))->offset;
2287 switch (iptr[1].op1) {
2289 M_IST(REG_ZERO, s1, disp);
2292 M_LST(REG_ZERO, s1, disp);
2295 M_AST(REG_ZERO, s1, disp);
2298 M_FST(REG_ZERO, s1, disp);
2301 M_DST(REG_ZERO, s1, disp);
2307 /* branch operations **************************************************/
2309 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
2311 var_to_reg_int(s1, src, REG_ITMP1);
2312 M_INTMOVE(s1, REG_ITMP1_XPTR);
2314 #ifdef ENABLE_VERIFIER
2316 codegen_addpatchref(cd, mcodeptr,
2317 PATCHER_athrow_areturn,
2318 (unresolved_class *) iptr->val.a, 0);
2320 if (opt_showdisassemble)
2323 #endif /* ENABLE_VERIFIER */
2325 disp = dseg_addaddress(cd, asm_handle_exception);
2326 M_ALD(REG_ITMP2, REG_PV, disp);
2327 M_JMP(REG_ITMP2_XPC, REG_ITMP2);
2328 M_NOP; /* nop ensures that XPC is less than the end */
2329 /* of basic block */
2333 case ICMD_GOTO: /* ... ==> ... */
2334 /* op1 = target JavaVM pc */
2336 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2340 case ICMD_JSR: /* ... ==> ... */
2341 /* op1 = target JavaVM pc */
2343 M_BSR(REG_ITMP1, 0);
2344 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2347 case ICMD_RET: /* ... ==> ... */
2348 /* op1 = local variable */
2350 var = &(rd->locals[iptr->op1][TYPE_ADR]);
2351 if (var->flags & INMEMORY) {
2352 M_ALD(REG_ITMP1, REG_SP, 8 * var->regoff);
2353 M_RET(REG_ZERO, REG_ITMP1);
2356 M_RET(REG_ZERO, var->regoff);
2360 case ICMD_IFNULL: /* ..., value ==> ... */
2361 /* op1 = target JavaVM pc */
2363 var_to_reg_int(s1, src, REG_ITMP1);
2365 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2368 case ICMD_IFNONNULL: /* ..., value ==> ... */
2369 /* op1 = target JavaVM pc */
2371 var_to_reg_int(s1, src, REG_ITMP1);
2373 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2376 case ICMD_IFEQ: /* ..., value ==> ... */
2377 /* op1 = target JavaVM pc, val.i = constant */
2379 var_to_reg_int(s1, src, REG_ITMP1);
2380 if (iptr->val.i == 0) {
2384 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2385 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2388 ICONST(REG_ITMP2, iptr->val.i);
2389 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2391 M_BNEZ(REG_ITMP1, 0);
2393 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2396 case ICMD_IFLT: /* ..., value ==> ... */
2397 /* op1 = target JavaVM pc, val.i = constant */
2399 var_to_reg_int(s1, src, REG_ITMP1);
2400 if (iptr->val.i == 0) {
2404 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2405 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2408 ICONST(REG_ITMP2, iptr->val.i);
2409 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2411 M_BNEZ(REG_ITMP1, 0);
2413 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2416 case ICMD_IFLE: /* ..., value ==> ... */
2417 /* op1 = target JavaVM pc, val.i = constant */
2419 var_to_reg_int(s1, src, REG_ITMP1);
2420 if (iptr->val.i == 0) {
2424 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2425 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2428 ICONST(REG_ITMP2, iptr->val.i);
2429 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2431 M_BNEZ(REG_ITMP1, 0);
2433 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2436 case ICMD_IFNE: /* ..., value ==> ... */
2437 /* op1 = target JavaVM pc, val.i = constant */
2439 var_to_reg_int(s1, src, REG_ITMP1);
2440 if (iptr->val.i == 0) {
2444 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2445 M_CMPEQ_IMM(s1, iptr->val.i, REG_ITMP1);
2448 ICONST(REG_ITMP2, iptr->val.i);
2449 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2451 M_BEQZ(REG_ITMP1, 0);
2453 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2456 case ICMD_IFGT: /* ..., value ==> ... */
2457 /* op1 = target JavaVM pc, val.i = constant */
2459 var_to_reg_int(s1, src, REG_ITMP1);
2460 if (iptr->val.i == 0) {
2464 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2465 M_CMPLE_IMM(s1, iptr->val.i, REG_ITMP1);
2468 ICONST(REG_ITMP2, iptr->val.i);
2469 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2471 M_BEQZ(REG_ITMP1, 0);
2473 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2476 case ICMD_IFGE: /* ..., value ==> ... */
2477 /* op1 = target JavaVM pc, val.i = constant */
2479 var_to_reg_int(s1, src, REG_ITMP1);
2480 if (iptr->val.i == 0) {
2484 if ((iptr->val.i > 0) && (iptr->val.i <= 255)) {
2485 M_CMPLT_IMM(s1, iptr->val.i, REG_ITMP1);
2488 ICONST(REG_ITMP2, iptr->val.i);
2489 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2491 M_BEQZ(REG_ITMP1, 0);
2493 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2496 case ICMD_IF_LEQ: /* ..., value ==> ... */
2497 /* op1 = target JavaVM pc, val.l = constant */
2499 var_to_reg_int(s1, src, REG_ITMP1);
2500 if (iptr->val.l == 0) {
2504 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2505 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2508 LCONST(REG_ITMP2, iptr->val.l);
2509 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2511 M_BNEZ(REG_ITMP1, 0);
2513 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2516 case ICMD_IF_LLT: /* ..., value ==> ... */
2517 /* op1 = target JavaVM pc, val.l = constant */
2519 var_to_reg_int(s1, src, REG_ITMP1);
2520 if (iptr->val.l == 0) {
2524 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2525 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2528 LCONST(REG_ITMP2, iptr->val.l);
2529 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2531 M_BNEZ(REG_ITMP1, 0);
2533 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2536 case ICMD_IF_LLE: /* ..., value ==> ... */
2537 /* op1 = target JavaVM pc, val.l = constant */
2539 var_to_reg_int(s1, src, REG_ITMP1);
2540 if (iptr->val.l == 0) {
2544 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2545 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2548 LCONST(REG_ITMP2, iptr->val.l);
2549 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2551 M_BNEZ(REG_ITMP1, 0);
2553 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2556 case ICMD_IF_LNE: /* ..., value ==> ... */
2557 /* op1 = target JavaVM pc, val.l = constant */
2559 var_to_reg_int(s1, src, REG_ITMP1);
2560 if (iptr->val.l == 0) {
2564 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2565 M_CMPEQ_IMM(s1, iptr->val.l, REG_ITMP1);
2568 LCONST(REG_ITMP2, iptr->val.l);
2569 M_CMPEQ(s1, REG_ITMP2, REG_ITMP1);
2571 M_BEQZ(REG_ITMP1, 0);
2573 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2576 case ICMD_IF_LGT: /* ..., value ==> ... */
2577 /* op1 = target JavaVM pc, val.l = constant */
2579 var_to_reg_int(s1, src, REG_ITMP1);
2580 if (iptr->val.l == 0) {
2584 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2585 M_CMPLE_IMM(s1, iptr->val.l, REG_ITMP1);
2588 LCONST(REG_ITMP2, iptr->val.l);
2589 M_CMPLE(s1, REG_ITMP2, REG_ITMP1);
2591 M_BEQZ(REG_ITMP1, 0);
2593 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2596 case ICMD_IF_LGE: /* ..., value ==> ... */
2597 /* op1 = target JavaVM pc, val.l = constant */
2599 var_to_reg_int(s1, src, REG_ITMP1);
2600 if (iptr->val.l == 0) {
2604 if ((iptr->val.l > 0) && (iptr->val.l <= 255)) {
2605 M_CMPLT_IMM(s1, iptr->val.l, REG_ITMP1);
2608 LCONST(REG_ITMP2, iptr->val.l);
2609 M_CMPLT(s1, REG_ITMP2, REG_ITMP1);
2611 M_BEQZ(REG_ITMP1, 0);
2613 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2616 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
2617 case ICMD_IF_LCMPEQ: /* op1 = target JavaVM pc */
2618 case ICMD_IF_ACMPEQ:
2620 var_to_reg_int(s1, src->prev, REG_ITMP1);
2621 var_to_reg_int(s2, src, REG_ITMP2);
2622 M_CMPEQ(s1, s2, REG_ITMP1);
2623 M_BNEZ(REG_ITMP1, 0);
2624 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2627 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
2628 case ICMD_IF_LCMPNE: /* op1 = target JavaVM pc */
2629 case ICMD_IF_ACMPNE:
2631 var_to_reg_int(s1, src->prev, REG_ITMP1);
2632 var_to_reg_int(s2, src, REG_ITMP2);
2633 M_CMPEQ(s1, s2, REG_ITMP1);
2634 M_BEQZ(REG_ITMP1, 0);
2635 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2638 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
2639 case ICMD_IF_LCMPLT: /* op1 = target JavaVM pc */
2641 var_to_reg_int(s1, src->prev, REG_ITMP1);
2642 var_to_reg_int(s2, src, REG_ITMP2);
2643 M_CMPLT(s1, s2, REG_ITMP1);
2644 M_BNEZ(REG_ITMP1, 0);
2645 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2648 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
2649 case ICMD_IF_LCMPGT: /* op1 = target JavaVM pc */
2651 var_to_reg_int(s1, src->prev, REG_ITMP1);
2652 var_to_reg_int(s2, src, REG_ITMP2);
2653 M_CMPLE(s1, s2, REG_ITMP1);
2654 M_BEQZ(REG_ITMP1, 0);
2655 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2658 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
2659 case ICMD_IF_LCMPLE: /* op1 = target JavaVM pc */
2661 var_to_reg_int(s1, src->prev, REG_ITMP1);
2662 var_to_reg_int(s2, src, REG_ITMP2);
2663 M_CMPLE(s1, s2, REG_ITMP1);
2664 M_BNEZ(REG_ITMP1, 0);
2665 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2668 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
2669 case ICMD_IF_LCMPGE: /* op1 = target JavaVM pc */
2671 var_to_reg_int(s1, src->prev, REG_ITMP1);
2672 var_to_reg_int(s2, src, REG_ITMP2);
2673 M_CMPLT(s1, s2, REG_ITMP1);
2674 M_BEQZ(REG_ITMP1, 0);
2675 codegen_addreference(cd, (basicblock *) iptr->target, mcodeptr);
2678 /* (value xx 0) ? IFxx_ICONST : ELSE_ICONST */
2680 case ICMD_ELSE_ICONST: /* handled by IFxx_ICONST */
2683 case ICMD_IFEQ_ICONST: /* ..., value ==> ..., constant */
2684 /* val.i = constant */
2686 var_to_reg_int(s1, src, REG_ITMP1);
2687 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2689 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2690 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2691 M_CMPEQ(s1, REG_ZERO, d);
2692 store_reg_to_var_int(iptr->dst, d);
2695 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2696 M_CMPEQ(s1, REG_ZERO, d);
2698 store_reg_to_var_int(iptr->dst, d);
2702 M_MOV(s1, REG_ITMP1);
2705 ICONST(d, iptr[1].val.i);
2707 if ((s3 >= 0) && (s3 <= 255)) {
2708 M_CMOVEQ_IMM(s1, s3, d);
2710 ICONST(REG_ITMP3, s3);
2711 M_CMOVEQ(s1, REG_ITMP3, d);
2713 store_reg_to_var_int(iptr->dst, d);
2716 case ICMD_IFNE_ICONST: /* ..., value ==> ..., constant */
2717 /* val.i = constant */
2719 var_to_reg_int(s1, src, REG_ITMP1);
2720 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2722 if (iptr[1].opc == ICMD_ELSE_ICONST) {
2723 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2724 M_CMPEQ(s1, REG_ZERO, d);
2725 store_reg_to_var_int(iptr->dst, d);
2728 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2729 M_CMPEQ(s1, REG_ZERO, d);
2731 store_reg_to_var_int(iptr->dst, d);
2735 M_MOV(s1, REG_ITMP1);
2738 ICONST(d, iptr[1].val.i);
2740 if ((s3 >= 0) && (s3 <= 255)) {
2741 M_CMOVNE_IMM(s1, s3, d);
2743 ICONST(REG_ITMP3, s3);
2744 M_CMOVNE(s1, REG_ITMP3, d);
2746 store_reg_to_var_int(iptr->dst, d);
2749 case ICMD_IFLT_ICONST: /* ..., value ==> ..., constant */
2750 /* val.i = constant */
2752 var_to_reg_int(s1, src, REG_ITMP1);
2753 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2755 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2756 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2757 M_CMPLT(s1, REG_ZERO, d);
2758 store_reg_to_var_int(iptr->dst, d);
2761 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2762 M_CMPLE(REG_ZERO, s1, d);
2763 store_reg_to_var_int(iptr->dst, d);
2767 M_MOV(s1, REG_ITMP1);
2770 ICONST(d, iptr[1].val.i);
2772 if ((s3 >= 0) && (s3 <= 255)) {
2773 M_CMOVLT_IMM(s1, s3, d);
2775 ICONST(REG_ITMP3, s3);
2776 M_CMOVLT(s1, REG_ITMP3, d);
2778 store_reg_to_var_int(iptr->dst, d);
2781 case ICMD_IFGE_ICONST: /* ..., value ==> ..., constant */
2782 /* val.i = constant */
2784 var_to_reg_int(s1, src, REG_ITMP1);
2785 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2787 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2788 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2789 M_CMPLE(REG_ZERO, s1, d);
2790 store_reg_to_var_int(iptr->dst, d);
2793 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2794 M_CMPLT(s1, REG_ZERO, d);
2795 store_reg_to_var_int(iptr->dst, d);
2799 M_MOV(s1, REG_ITMP1);
2802 ICONST(d, iptr[1].val.i);
2804 if ((s3 >= 0) && (s3 <= 255)) {
2805 M_CMOVGE_IMM(s1, s3, d);
2807 ICONST(REG_ITMP3, s3);
2808 M_CMOVGE(s1, REG_ITMP3, d);
2810 store_reg_to_var_int(iptr->dst, d);
2813 case ICMD_IFGT_ICONST: /* ..., value ==> ..., constant */
2814 /* val.i = constant */
2816 var_to_reg_int(s1, src, REG_ITMP1);
2817 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2819 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2820 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2821 M_CMPLT(REG_ZERO, s1, d);
2822 store_reg_to_var_int(iptr->dst, d);
2825 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2826 M_CMPLE(s1, REG_ZERO, d);
2827 store_reg_to_var_int(iptr->dst, d);
2831 M_MOV(s1, REG_ITMP1);
2834 ICONST(d, iptr[1].val.i);
2836 if ((s3 >= 0) && (s3 <= 255)) {
2837 M_CMOVGT_IMM(s1, s3, d);
2839 ICONST(REG_ITMP3, s3);
2840 M_CMOVGT(s1, REG_ITMP3, d);
2842 store_reg_to_var_int(iptr->dst, d);
2845 case ICMD_IFLE_ICONST: /* ..., value ==> ..., constant */
2846 /* val.i = constant */
2848 var_to_reg_int(s1, src, REG_ITMP1);
2849 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
2851 if ((iptr[1].opc == ICMD_ELSE_ICONST)) {
2852 if ((s3 == 1) && (iptr[1].val.i == 0)) {
2853 M_CMPLE(s1, REG_ZERO, d);
2854 store_reg_to_var_int(iptr->dst, d);
2857 if ((s3 == 0) && (iptr[1].val.i == 1)) {
2858 M_CMPLT(REG_ZERO, s1, d);
2859 store_reg_to_var_int(iptr->dst, d);
2863 M_MOV(s1, REG_ITMP1);
2866 ICONST(d, iptr[1].val.i);
2868 if ((s3 >= 0) && (s3 <= 255)) {
2869 M_CMOVLE_IMM(s1, s3, d);
2871 ICONST(REG_ITMP3, s3);
2872 M_CMOVLE(s1, REG_ITMP3, d);
2874 store_reg_to_var_int(iptr->dst, d);
2878 case ICMD_IRETURN: /* ..., retvalue ==> ... */
2881 var_to_reg_int(s1, src, REG_RESULT);
2882 M_INTMOVE(s1, REG_RESULT);
2883 goto nowperformreturn;
2885 case ICMD_ARETURN: /* ..., retvalue ==> ... */
2887 var_to_reg_int(s1, src, REG_RESULT);
2888 M_INTMOVE(s1, REG_RESULT);
2890 #ifdef ENABLE_VERIFIER
2892 codegen_addpatchref(cd, mcodeptr,
2893 PATCHER_athrow_areturn,
2894 (unresolved_class *) iptr->val.a, 0);
2896 if (opt_showdisassemble)
2899 #endif /* ENABLE_VERIFIER */
2900 goto nowperformreturn;
2902 case ICMD_FRETURN: /* ..., retvalue ==> ... */
2905 var_to_reg_flt(s1, src, REG_FRESULT);
2906 M_FLTMOVE(s1, REG_FRESULT);
2907 goto nowperformreturn;
2909 case ICMD_RETURN: /* ... ==> ... */
2915 p = parentargs_base;
2917 /* call trace function */
2919 if (opt_verbosecall) {
2920 M_LDA(REG_SP, REG_SP, -3 * 8);
2921 M_AST(REG_RA, REG_SP, 0 * 8);
2922 M_LST(REG_RESULT, REG_SP, 1 * 8);
2923 M_DST(REG_FRESULT, REG_SP, 2 * 8);
2925 disp = dseg_addaddress(cd, m);
2926 M_ALD(rd->argintregs[0], REG_PV, disp);
2927 M_MOV(REG_RESULT, rd->argintregs[1]);
2928 M_FLTMOVE(REG_FRESULT, rd->argfltregs[2]);
2929 M_FLTMOVE(REG_FRESULT, rd->argfltregs[3]);
2931 disp = dseg_addaddress(cd, (void *) builtin_displaymethodstop);
2932 M_ALD(REG_PV, REG_PV, disp);
2933 M_JSR(REG_RA, REG_PV);
2934 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
2935 M_LDA(REG_PV, REG_RA, -disp);
2937 M_DLD(REG_FRESULT, REG_SP, 2 * 8);
2938 M_LLD(REG_RESULT, REG_SP, 1 * 8);
2939 M_ALD(REG_RA, REG_SP, 0 * 8);
2940 M_LDA(REG_SP, REG_SP, 3 * 8);
2943 #if defined(USE_THREADS)
2944 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
2945 M_ALD(rd->argintregs[0], REG_SP, rd->memuse * 8);
2947 switch (iptr->opc) {
2951 M_LST(REG_RESULT, REG_SP, rd->memuse * 8);
2955 M_DST(REG_FRESULT, REG_SP, rd->memuse * 8);
2959 disp = dseg_addaddress(cd, BUILTIN_monitorexit);
2960 M_ALD(REG_PV, REG_PV, disp);
2961 M_JSR(REG_RA, REG_PV);
2962 disp = -(s4) ((u1 *) mcodeptr - cd->mcodebase);
2963 M_LDA(REG_PV, REG_RA, disp);
2965 switch (iptr->opc) {
2969 M_LLD(REG_RESULT, REG_SP, rd->memuse * 8);
2973 M_DLD(REG_FRESULT, REG_SP, rd->memuse * 8);
2979 /* restore return address */
2981 if (!m->isleafmethod) {
2982 p--; M_LLD(REG_RA, REG_SP, p * 8);
2985 /* restore saved registers */
2987 for (i = INT_SAV_CNT - 1; i >= rd->savintreguse; i--) {
2988 p--; M_LLD(rd->savintregs[i], REG_SP, p * 8);
2990 for (i = FLT_SAV_CNT - 1; i >= rd->savfltreguse; i--) {
2991 p--; M_DLD(rd->savfltregs[i], REG_SP, p * 8);
2994 /* deallocate stack */
2996 if (parentargs_base) {
2997 M_LDA(REG_SP, REG_SP, parentargs_base * 8);
3000 M_RET(REG_ZERO, REG_RA);
3006 case ICMD_TABLESWITCH: /* ..., index ==> ... */
3011 tptr = (void **) iptr->target;
3013 s4ptr = iptr->val.a;
3014 l = s4ptr[1]; /* low */
3015 i = s4ptr[2]; /* high */
3017 var_to_reg_int(s1, src, REG_ITMP1);
3019 M_INTMOVE(s1, REG_ITMP1);
3020 } else if (l <= 32768) {
3021 M_LDA(REG_ITMP1, s1, -l);
3023 ICONST(REG_ITMP2, l);
3024 M_ISUB(s1, REG_ITMP2, REG_ITMP1);
3031 M_CMPULE_IMM(REG_ITMP1, i - 1, REG_ITMP2);
3033 M_LDA(REG_ITMP2, REG_ZERO, i - 1);
3034 M_CMPULE(REG_ITMP1, REG_ITMP2, REG_ITMP2);
3036 M_BEQZ(REG_ITMP2, 0);
3037 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3039 /* build jump table top down and use address of lowest entry */
3041 /* s4ptr += 3 + i; */
3045 dseg_addtarget(cd, (basicblock *) tptr[0]);
3050 /* length of dataseg after last dseg_addtarget is used by load */
3052 M_SAADDQ(REG_ITMP1, REG_PV, REG_ITMP2);
3053 M_ALD(REG_ITMP2, REG_ITMP2, -(cd->dseglen));
3054 M_JMP(REG_ZERO, REG_ITMP2);
3059 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
3061 s4 i, l, val, *s4ptr;
3064 tptr = (void **) iptr->target;
3066 s4ptr = iptr->val.a;
3067 l = s4ptr[0]; /* default */
3068 i = s4ptr[1]; /* count */
3070 MCODECHECK((i<<2)+8);
3071 var_to_reg_int(s1, src, REG_ITMP1);
3077 if ((val >= 0) && (val <= 255)) {
3078 M_CMPEQ_IMM(s1, val, REG_ITMP2);
3080 if ((val >= -32768) && (val <= 32767)) {
3081 M_LDA(REG_ITMP2, REG_ZERO, val);
3083 disp = dseg_adds4(cd, val);
3084 M_ILD(REG_ITMP2, REG_PV, disp);
3086 M_CMPEQ(s1, REG_ITMP2, REG_ITMP2);
3088 M_BNEZ(REG_ITMP2, 0);
3089 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3094 tptr = (void **) iptr->target;
3095 codegen_addreference(cd, (basicblock *) tptr[0], mcodeptr);
3102 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
3103 /* op1 = arg count val.a = builtintable entry */
3109 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
3110 /* op1 = arg count, val.a = method pointer */
3112 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
3113 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
3114 case ICMD_INVOKEINTERFACE:
3119 unresolved_method *um = iptr->target;
3120 md = um->methodref->parseddesc.md;
3122 md = lm->parseddesc;
3126 s3 = md->paramcount;
3128 MCODECHECK((s3 << 1) + 64);
3130 /* copy arguments to registers or stack location */
3132 for (s3 = s3 - 1; s3 >= 0; s3--, src = src->prev) {
3133 if (src->varkind == ARGVAR)
3135 if (IS_INT_LNG_TYPE(src->type)) {
3136 if (!md->params[s3].inmemory) {
3137 s1 = rd->argintregs[md->params[s3].regoff];
3138 var_to_reg_int(d, src, s1);
3141 var_to_reg_int(d, src, REG_ITMP1);
3142 M_LST(d, REG_SP, md->params[s3].regoff * 8);
3146 if (!md->params[s3].inmemory) {
3147 s1 = rd->argfltregs[md->params[s3].regoff];
3148 var_to_reg_flt(d, src, s1);
3151 var_to_reg_flt(d, src, REG_FTMP1);
3152 M_DST(d, REG_SP, md->params[s3].regoff * 8);
3157 switch (iptr->opc) {
3159 disp = dseg_addaddress(cd, bte->fp);
3160 d = md->returntype.type;
3162 M_ALD(REG_PV, REG_PV, disp); /* Pointer to built-in-function */
3163 M_JSR(REG_RA, REG_PV);
3164 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3165 M_LDA(REG_PV, REG_RA, -disp);
3167 /* if op1 == true, we need to check for an exception */
3169 if (iptr->op1 == true) {
3170 M_BEQZ(REG_RESULT, 0);
3171 codegen_addxexceptionrefs(cd, mcodeptr);
3175 case ICMD_INVOKESPECIAL:
3176 M_BEQZ(rd->argintregs[0], 0);
3177 codegen_addxnullrefs(cd, mcodeptr);
3180 case ICMD_INVOKESTATIC:
3182 unresolved_method *um = iptr->target;
3184 disp = dseg_addaddress(cd, NULL);
3186 codegen_addpatchref(cd, mcodeptr,
3187 PATCHER_invokestatic_special, um, disp);
3189 if (opt_showdisassemble)
3192 d = um->methodref->parseddesc.md->returntype.type;
3195 disp = dseg_addaddress(cd, lm->stubroutine);
3196 d = lm->parseddesc->returntype.type;
3199 M_ALD(REG_PV, REG_PV, disp); /* method pointer in r27 */
3200 M_JSR(REG_RA, REG_PV);
3201 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3202 M_LDA(REG_PV, REG_RA, -disp);
3205 case ICMD_INVOKEVIRTUAL:
3206 gen_nullptr_check(rd->argintregs[0]);
3209 unresolved_method *um = iptr->target;
3211 codegen_addpatchref(cd, mcodeptr,
3212 PATCHER_invokevirtual, um, 0);
3214 if (opt_showdisassemble)
3218 d = um->methodref->parseddesc.md->returntype.type;
3221 s1 = OFFSET(vftbl_t, table[0]) +
3222 sizeof(methodptr) * lm->vftblindex;
3223 d = lm->parseddesc->returntype.type;
3226 M_ALD(REG_METHODPTR, rd->argintregs[0],
3227 OFFSET(java_objectheader, vftbl));
3228 M_ALD(REG_PV, REG_METHODPTR, s1);
3229 M_JSR(REG_RA, REG_PV);
3230 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3231 M_LDA(REG_PV, REG_RA, -disp);
3234 case ICMD_INVOKEINTERFACE:
3235 gen_nullptr_check(rd->argintregs[0]);
3238 unresolved_method *um = iptr->target;
3240 codegen_addpatchref(cd, mcodeptr,
3241 PATCHER_invokeinterface, um, 0);
3243 if (opt_showdisassemble)
3248 d = um->methodref->parseddesc.md->returntype.type;
3251 s1 = OFFSET(vftbl_t, interfacetable[0]) -
3252 sizeof(methodptr*) * lm->class->index;
3254 s2 = sizeof(methodptr) * (lm - lm->class->methods);
3256 d = lm->parseddesc->returntype.type;
3259 M_ALD(REG_METHODPTR, rd->argintregs[0],
3260 OFFSET(java_objectheader, vftbl));
3261 M_ALD(REG_METHODPTR, REG_METHODPTR, s1);
3262 M_ALD(REG_PV, REG_METHODPTR, s2);
3263 M_JSR(REG_RA, REG_PV);
3264 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3265 M_LDA(REG_PV, REG_RA, -disp);
3269 /* d contains return type */
3271 if (d != TYPE_VOID) {
3272 if (IS_INT_LNG_TYPE(iptr->dst->type)) {
3273 s1 = reg_of_var(rd, iptr->dst, REG_RESULT);
3274 M_INTMOVE(REG_RESULT, s1);
3275 store_reg_to_var_int(iptr->dst, s1);
3277 s1 = reg_of_var(rd, iptr->dst, REG_FRESULT);
3278 M_FLTMOVE(REG_FRESULT, s1);
3279 store_reg_to_var_flt(iptr->dst, s1);
3285 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
3287 /* op1: 0 == array, 1 == class */
3288 /* val.a: (classinfo*) superclass */
3290 /* superclass is an interface:
3292 * OK if ((sub == NULL) ||
3293 * (sub->vftbl->interfacetablelength > super->index) &&
3294 * (sub->vftbl->interfacetable[-super->index] != NULL));
3296 * superclass is a class:
3298 * OK if ((sub == NULL) || (0
3299 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3300 * super->vftbl->diffval));
3303 if (iptr->op1 == 1) {
3304 /* object type cast-check */
3307 vftbl_t *supervftbl;
3310 super = (classinfo *) iptr->val.a;
3317 superindex = super->index;
3318 supervftbl = super->vftbl;
3321 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3322 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3324 var_to_reg_int(s1, src, REG_ITMP1);
3326 /* calculate interface checkcast code size */
3330 s2 += opt_showdisassemble ? 1 : 0;
3332 /* calculate class checkcast code size */
3334 s3 = 9 /* 8 + (s1 == REG_ITMP1) */;
3336 s3 += opt_showdisassemble ? 1 : 0;
3338 /* if class is not resolved, check which code to call */
3341 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3343 disp = dseg_adds4(cd, 0); /* super->flags */
3345 codegen_addpatchref(cd, mcodeptr,
3346 PATCHER_checkcast_instanceof_flags,
3347 (constant_classref *) iptr->target,
3350 if (opt_showdisassemble)
3353 M_ILD(REG_ITMP2, REG_PV, disp);
3354 disp = dseg_adds4(cd, ACC_INTERFACE);
3355 M_ILD(REG_ITMP3, REG_PV, disp);
3356 M_AND(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3357 M_BEQZ(REG_ITMP2, s2 + 1);
3360 /* interface checkcast code */
3362 if (!super || (super->flags & ACC_INTERFACE)) {
3367 codegen_addpatchref(cd, mcodeptr,
3368 PATCHER_checkcast_instanceof_interface,
3369 (constant_classref *) iptr->target,
3372 if (opt_showdisassemble)
3376 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3377 M_ILD(REG_ITMP3, REG_ITMP2,
3378 OFFSET(vftbl_t, interfacetablelength));
3379 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3380 M_BLEZ(REG_ITMP3, 0);
3381 codegen_addxcastrefs(cd, mcodeptr);
3382 M_ALD(REG_ITMP3, REG_ITMP2,
3383 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3384 superindex * sizeof(methodptr*)));
3385 M_BEQZ(REG_ITMP3, 0);
3386 codegen_addxcastrefs(cd, mcodeptr);
3392 /* class checkcast code */
3394 if (!super || !(super->flags & ACC_INTERFACE)) {
3395 disp = dseg_addaddress(cd, supervftbl);
3401 codegen_addpatchref(cd, mcodeptr,
3402 PATCHER_checkcast_instanceof_class,
3403 (constant_classref *) iptr->target,
3406 if (opt_showdisassemble)
3410 M_ALD(REG_ITMP2, s1, OFFSET(java_objectheader, vftbl));
3411 M_ALD(REG_ITMP3, REG_PV, disp);
3412 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3413 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3415 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
3416 /* if (s1 != REG_ITMP1) { */
3417 /* M_ILD(REG_ITMP1, REG_ITMP3, OFFSET(vftbl_t, baseval)); */
3418 /* M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval)); */
3419 /* #if defined(USE_THREADS) && defined(NATIVE_THREADS) */
3420 /* codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase); */
3422 /* M_ISUB(REG_ITMP2, REG_ITMP1, REG_ITMP2); */
3425 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
3426 M_ISUB(REG_ITMP2, REG_ITMP3, REG_ITMP2);
3427 M_ALD(REG_ITMP3, REG_PV, disp);
3428 M_ILD(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
3429 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3430 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3433 M_CMPULE(REG_ITMP2, REG_ITMP3, REG_ITMP3);
3434 M_BEQZ(REG_ITMP3, 0);
3435 codegen_addxcastrefs(cd, mcodeptr);
3437 d = reg_of_var(rd, iptr->dst, s1);
3440 /* array type cast-check */
3442 var_to_reg_int(s1, src, rd->argintregs[0]);
3443 M_INTMOVE(s1, rd->argintregs[0]);
3445 disp = dseg_addaddress(cd, iptr->val.a);
3447 if (iptr->val.a == NULL) {
3448 codegen_addpatchref(cd, mcodeptr,
3449 PATCHER_builtin_arraycheckcast,
3450 (constant_classref *) iptr->target,
3453 if (opt_showdisassemble)
3457 M_ALD(rd->argintregs[1], REG_PV, disp);
3458 disp = dseg_addaddress(cd, BUILTIN_arraycheckcast);
3459 M_ALD(REG_PV, REG_PV, disp);
3460 M_JSR(REG_RA, REG_PV);
3461 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3462 M_LDA(REG_PV, REG_RA, -disp);
3464 M_BEQZ(REG_RESULT, 0);
3465 codegen_addxcastrefs(cd, mcodeptr);
3467 var_to_reg_int(s1, src, REG_ITMP1);
3468 d = reg_of_var(rd, iptr->dst, s1);
3471 store_reg_to_var_int(iptr->dst, d);
3474 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
3476 /* op1: 0 == array, 1 == class */
3477 /* val.a: (classinfo*) superclass */
3479 /* superclass is an interface:
3481 * return (sub != NULL) &&
3482 * (sub->vftbl->interfacetablelength > super->index) &&
3483 * (sub->vftbl->interfacetable[-super->index] != NULL);
3485 * superclass is a class:
3487 * return ((sub != NULL) && (0
3488 * <= (sub->vftbl->baseval - super->vftbl->baseval) <=
3489 * super->vftbl->diffvall));
3494 vftbl_t *supervftbl;
3497 super = (classinfo *) iptr->val.a;
3504 superindex = super->index;
3505 supervftbl = super->vftbl;
3508 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3509 codegen_threadcritrestart(cd, (u1 *) mcodeptr - cd->mcodebase);
3511 var_to_reg_int(s1, src, REG_ITMP1);
3512 d = reg_of_var(rd, iptr->dst, REG_ITMP2);
3514 M_MOV(s1, REG_ITMP1);
3518 /* calculate interface instanceof code size */
3522 s2 += (d == REG_ITMP2 ? 1 : 0) + (opt_showdisassemble ? 1 : 0);
3524 /* calculate class instanceof code size */
3528 s3 += (opt_showdisassemble ? 1 : 0);
3530 /* if class is not resolved, check which code to call */
3534 M_BEQZ(s1, 4 + (opt_showdisassemble ? 1 : 0) + s2 + 1 + s3);
3536 disp = dseg_adds4(cd, 0); /* super->flags */
3538 codegen_addpatchref(cd, mcodeptr,
3539 PATCHER_checkcast_instanceof_flags,
3540 (constant_classref *) iptr->target, disp);
3542 if (opt_showdisassemble)
3545 M_ILD(REG_ITMP3, REG_PV, disp);
3547 disp = dseg_adds4(cd, ACC_INTERFACE);
3548 M_ILD(REG_ITMP2, REG_PV, disp);
3549 M_AND(REG_ITMP3, REG_ITMP2, REG_ITMP3);
3550 M_BEQZ(REG_ITMP3, s2 + 1);
3553 /* interface instanceof code */
3555 if (!super || (super->flags & ACC_INTERFACE)) {
3561 /* If d == REG_ITMP2, then it's destroyed in check code */
3566 codegen_addpatchref(cd, mcodeptr,
3567 PATCHER_checkcast_instanceof_interface,
3568 (constant_classref *) iptr->target, 0);
3570 if (opt_showdisassemble)
3574 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3575 M_ILD(REG_ITMP3, REG_ITMP1, OFFSET(vftbl_t, interfacetablelength));
3576 M_LDA(REG_ITMP3, REG_ITMP3, -superindex);
3577 M_BLEZ(REG_ITMP3, 2);
3578 M_ALD(REG_ITMP1, REG_ITMP1,
3579 (s4) (OFFSET(vftbl_t, interfacetable[0]) -
3580 superindex * sizeof(methodptr*)));
3581 M_CMPULT(REG_ZERO, REG_ITMP1, d); /* REG_ITMP1 != 0 */
3587 /* class instanceof code */
3589 if (!super || !(super->flags & ACC_INTERFACE)) {
3590 disp = dseg_addaddress(cd, supervftbl);
3597 codegen_addpatchref(cd, mcodeptr,
3598 PATCHER_checkcast_instanceof_class,
3599 (constant_classref *) iptr->target,
3602 if (opt_showdisassemble)
3606 M_ALD(REG_ITMP1, s1, OFFSET(java_objectheader, vftbl));
3607 M_ALD(REG_ITMP2, REG_PV, disp);
3608 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3609 codegen_threadcritstart(cd, (u1 *) mcodeptr - cd->mcodebase);
3611 M_ILD(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
3612 M_ILD(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
3613 M_ILD(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
3614 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
3615 codegen_threadcritstop(cd, (u1 *) mcodeptr - cd->mcodebase);
3617 M_ISUB(REG_ITMP1, REG_ITMP3, REG_ITMP1);
3618 M_CMPULE(REG_ITMP1, REG_ITMP2, d);
3620 store_reg_to_var_int(iptr->dst, d);
3624 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
3625 /* op1 = dimension, val.a = class */
3627 /* check for negative sizes and copy sizes to stack if necessary */
3629 MCODECHECK((iptr->op1 << 1) + 64);
3631 for (s1 = iptr->op1; --s1 >= 0; src = src->prev) {
3632 /* copy SAVEDVAR sizes to stack */
3634 if (src->varkind != ARGVAR) {
3635 var_to_reg_int(s2, src, REG_ITMP1);
3636 M_LST(s2, REG_SP, s1 * 8);
3640 /* a0 = dimension count */
3642 ICONST(rd->argintregs[0], iptr->op1);
3644 /* is patcher function set? */
3646 if (iptr->val.a == NULL) {
3647 disp = dseg_addaddress(cd, 0);
3649 codegen_addpatchref(cd, mcodeptr,
3650 PATCHER_builtin_multianewarray,
3651 (constant_classref *) iptr->target,
3654 if (opt_showdisassemble)
3658 disp = dseg_addaddress(cd, iptr->val.a);
3661 /* a1 = arraydescriptor */
3663 M_ALD(rd->argintregs[1], REG_PV, disp);
3665 /* a2 = pointer to dimensions = stack pointer */
3667 M_INTMOVE(REG_SP, rd->argintregs[2]);
3669 disp = dseg_addaddress(cd, BUILTIN_multianewarray);
3670 M_ALD(REG_PV, REG_PV, disp);
3671 M_JSR(REG_RA, REG_PV);
3672 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3673 M_LDA(REG_PV, REG_RA, -disp);
3675 /* check for exception before result assignment */
3677 M_BEQZ(REG_RESULT, 0);
3678 codegen_addxexceptionrefs(cd, mcodeptr);
3680 d = reg_of_var(rd, iptr->dst, REG_RESULT);
3681 M_INTMOVE(REG_RESULT, d);
3682 store_reg_to_var_int(iptr->dst, d);
3687 new_internalerror("Unknown ICMD %d", iptr->opc);
3691 } /* for instruction */
3693 /* copy values to interface registers */
3695 src = bptr->outstack;
3696 len = bptr->outdepth;
3698 #if defined(ENABLE_LSRA)
3703 if ((src->varkind != STACKVAR)) {
3705 if (IS_FLT_DBL_TYPE(s2)) {
3706 var_to_reg_flt(s1, src, REG_FTMP1);
3707 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3708 M_FLTMOVE(s1,rd->interfaces[len][s2].regoff);
3711 M_DST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3715 var_to_reg_int(s1, src, REG_ITMP1);
3716 if (!(rd->interfaces[len][s2].flags & INMEMORY)) {
3717 M_INTMOVE(s1,rd->interfaces[len][s2].regoff);
3720 M_LST(s1, REG_SP, 8 * rd->interfaces[len][s2].regoff);
3726 } /* if (bptr -> flags >= BBREACHED) */
3727 } /* for basic block */
3729 dseg_createlinenumbertable(cd);
3733 s4 *xcodeptr = NULL;
3736 /* generate ArithmeticException stubs */
3738 for (bref = cd->xdivrefs; bref != NULL; bref = bref->next) {
3739 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3741 (u1 *) mcodeptr - cd->mcodebase);
3745 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3747 if (xcodeptr != NULL) {
3748 disp = xcodeptr - mcodeptr - 1;
3752 xcodeptr = mcodeptr;
3754 M_MOV(REG_PV, rd->argintregs[0]);
3755 M_MOV(REG_SP, rd->argintregs[1]);
3756 M_ALD(rd->argintregs[2],
3757 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3758 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3760 M_LDA(REG_SP, REG_SP, -1 * 8);
3761 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3763 disp = dseg_addaddress(cd, stacktrace_inline_arithmeticexception);
3764 M_ALD(REG_PV, REG_PV, disp);
3765 M_JSR(REG_RA, REG_PV);
3766 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3767 M_LDA(REG_PV, REG_RA, -disp);
3769 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3771 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3772 M_LDA(REG_SP, REG_SP, 1 * 8);
3774 disp = dseg_addaddress(cd, asm_handle_exception);
3775 M_ALD(REG_ITMP3, REG_PV, disp);
3776 M_JMP(REG_ZERO, REG_ITMP3);
3780 /* generate ArrayIndexOutOfBoundsException stubs */
3784 for (bref = cd->xboundrefs; bref != NULL; bref = bref->next) {
3785 gen_resolvebranch((u1*) cd->mcodebase + bref->branchpos,
3787 (u1*) mcodeptr - cd->mcodebase);
3791 /* move index register into REG_ITMP1 */
3793 M_MOV(bref->reg, REG_ITMP1);
3794 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3796 if (xcodeptr != NULL) {
3797 disp = xcodeptr - mcodeptr - 1;
3801 xcodeptr = mcodeptr;
3803 M_MOV(REG_PV, rd->argintregs[0]);
3804 M_MOV(REG_SP, rd->argintregs[1]);
3806 if (m->isleafmethod)
3807 M_MOV(REG_RA, rd->argintregs[2]);
3809 M_ALD(rd->argintregs[2],
3810 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3812 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3813 M_MOV(REG_ITMP1, rd->argintregs[4]);
3815 M_LDA(REG_SP, REG_SP, -2 * 8);
3816 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3818 if (m->isleafmethod)
3819 M_AST(REG_RA, REG_SP, 1 * 8);
3821 disp = dseg_addaddress(cd, stacktrace_inline_arrayindexoutofboundsexception);
3822 M_ALD(REG_PV, REG_PV, disp);
3823 M_JSR(REG_RA, REG_PV);
3824 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3825 M_LDA(REG_PV, REG_RA, -disp);
3827 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3829 if (m->isleafmethod)
3830 M_ALD(REG_RA, REG_SP, 1 * 8);
3832 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3833 M_LDA(REG_SP, REG_SP, 2 * 8);
3835 disp = dseg_addaddress(cd, asm_handle_exception);
3836 M_ALD(REG_ITMP3, REG_PV, disp);
3837 M_JMP(REG_ZERO, REG_ITMP3);
3841 /* generate ArrayStoreException stubs */
3845 for (bref = cd->xstorerefs; bref != NULL; bref = bref->next) {
3846 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3848 (u1 *) mcodeptr - cd->mcodebase);
3852 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3854 if (xcodeptr != NULL) {
3855 disp = xcodeptr - mcodeptr - 1;
3859 xcodeptr = mcodeptr;
3861 M_MOV(REG_PV, rd->argintregs[0]);
3862 M_MOV(REG_SP, rd->argintregs[1]);
3863 M_ALD(rd->argintregs[2],
3864 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3865 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3867 M_LDA(REG_SP, REG_SP, -1 * 8);
3868 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3870 disp = dseg_addaddress(cd, stacktrace_inline_arraystoreexception);
3871 M_ALD(REG_PV, REG_PV, disp);
3872 M_JSR(REG_RA, REG_PV);
3873 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3874 M_LDA(REG_PV, REG_RA, -disp);
3876 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3878 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3879 M_LDA(REG_SP, REG_SP, 1 * 8);
3881 disp = dseg_addaddress(cd, asm_handle_exception);
3882 M_ALD(REG_ITMP3, REG_PV, disp);
3883 M_JMP(REG_ZERO, REG_ITMP3);
3887 /* generate ClassCastException stubs */
3891 for (bref = cd->xcastrefs; bref != NULL; bref = bref->next) {
3892 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3894 (u1 *) mcodeptr - cd->mcodebase);
3898 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3900 if (xcodeptr != NULL) {
3901 disp = xcodeptr - mcodeptr - 1;
3905 xcodeptr = mcodeptr;
3907 M_MOV(REG_PV, rd->argintregs[0]);
3908 M_MOV(REG_SP, rd->argintregs[1]);
3910 if (m->isleafmethod)
3911 M_MOV(REG_RA, rd->argintregs[2]);
3913 M_ALD(rd->argintregs[2],
3914 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3916 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3918 M_LDA(REG_SP, REG_SP, -2 * 8);
3919 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3921 if (m->isleafmethod)
3922 M_AST(REG_RA, REG_SP, 1 * 8);
3924 disp = dseg_addaddress(cd, stacktrace_inline_classcastexception);
3925 M_ALD(REG_PV, REG_PV, disp);
3926 M_JSR(REG_RA, REG_PV);
3927 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3928 M_LDA(REG_PV, REG_RA, -disp);
3930 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3932 if (m->isleafmethod)
3933 M_ALD(REG_RA, REG_SP, 1 * 8);
3935 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3936 M_LDA(REG_SP, REG_SP, 2 * 8);
3938 disp = dseg_addaddress(cd, asm_handle_exception);
3939 M_ALD(REG_ITMP3, REG_PV, disp);
3940 M_JMP(REG_ZERO, REG_ITMP3);
3944 /* generate NullPointerException stubs */
3948 for (bref = cd->xnullrefs; bref != NULL; bref = bref->next) {
3949 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
3951 (u1 *) mcodeptr - cd->mcodebase);
3955 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
3957 if (xcodeptr != NULL) {
3958 disp = xcodeptr - mcodeptr - 1;
3962 xcodeptr = mcodeptr;
3964 M_MOV(REG_PV, rd->argintregs[0]);
3965 M_MOV(REG_SP, rd->argintregs[1]);
3967 if (m->isleafmethod)
3968 M_MOV(REG_RA, rd->argintregs[2]);
3970 M_ALD(rd->argintregs[2],
3971 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
3973 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
3975 M_LDA(REG_SP, REG_SP, -2 * 8);
3976 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
3978 if (m->isleafmethod)
3979 M_AST(REG_RA, REG_SP, 1 * 8);
3981 disp = dseg_addaddress(cd, stacktrace_inline_nullpointerexception);
3982 M_ALD(REG_PV, REG_PV, disp);
3983 M_JSR(REG_RA, REG_PV);
3984 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
3985 M_LDA(REG_PV, REG_RA, -disp);
3987 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
3989 if (m->isleafmethod)
3990 M_ALD(REG_RA, REG_SP, 1 * 8);
3992 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
3993 M_LDA(REG_SP, REG_SP, 2 * 8);
3995 disp = dseg_addaddress(cd, asm_handle_exception);
3996 M_ALD(REG_ITMP3, REG_PV, disp);
3997 M_JMP(REG_ZERO, REG_ITMP3);
4001 /* generate exception check stubs */
4005 for (bref = cd->xexceptionrefs; bref != NULL; bref = bref->next) {
4006 gen_resolvebranch((u1 *) cd->mcodebase + bref->branchpos,
4008 (u1 *) mcodeptr - cd->mcodebase);
4012 M_LDA(REG_ITMP2_XPC, REG_PV, bref->branchpos - 4);
4014 if (xcodeptr != NULL) {
4015 disp = xcodeptr - mcodeptr - 1;
4019 xcodeptr = mcodeptr;
4021 M_MOV(REG_PV, rd->argintregs[0]);
4022 M_MOV(REG_SP, rd->argintregs[1]);
4023 M_ALD(rd->argintregs[2],
4024 REG_SP, parentargs_base * 8 - SIZEOF_VOID_P);
4025 M_MOV(REG_ITMP2_XPC, rd->argintregs[3]);
4027 M_LDA(REG_SP, REG_SP, -1 * 8);
4028 M_AST(REG_ITMP2_XPC, REG_SP, 0 * 8);
4030 disp = dseg_addaddress(cd, stacktrace_inline_fillInStackTrace);
4031 M_ALD(REG_PV, REG_PV, disp);
4032 M_JSR(REG_RA, REG_PV);
4033 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4034 M_LDA(REG_PV, REG_RA, -disp);
4036 M_MOV(REG_RESULT, REG_ITMP1_XPTR);
4038 M_ALD(REG_ITMP2_XPC, REG_SP, 0 * 8);
4039 M_LDA(REG_SP, REG_SP, 1 * 8);
4041 disp = dseg_addaddress(cd, asm_handle_exception);
4042 M_ALD(REG_ITMP3, REG_PV, disp);
4043 M_JMP(REG_ZERO, REG_ITMP3);
4047 /* generate patcher stub call code */
4054 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4055 /* check code segment size */
4059 /* Get machine code which is patched back in later. The call is */
4060 /* 1 instruction word long. */
4062 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4065 /* patch in the call to call the following code (done at compile */
4068 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4069 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4071 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4073 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4075 /* create stack frame */
4077 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4079 /* move return address onto stack */
4081 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4083 /* move pointer to java_objectheader onto stack */
4085 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4086 /* create a virtual java_objectheader */
4088 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4089 disp = dseg_addaddress(cd, NULL); /* vftbl */
4091 M_LDA(REG_ITMP3, REG_PV, disp);
4092 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4097 /* move machine code onto stack */
4099 disp = dseg_adds4(cd, mcode);
4100 M_ILD(REG_ITMP3, REG_PV, disp);
4101 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4103 /* move class/method/field reference onto stack */
4105 disp = dseg_addaddress(cd, pref->ref);
4106 M_ALD(REG_ITMP3, REG_PV, disp);
4107 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4109 /* move data segment displacement onto stack */
4111 disp = dseg_adds4(cd, pref->disp);
4112 M_ILD(REG_ITMP3, REG_PV, disp);
4113 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4115 /* move patcher function pointer onto stack */
4117 disp = dseg_addaddress(cd, pref->patcher);
4118 M_ALD(REG_ITMP3, REG_PV, disp);
4119 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4121 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4122 M_ALD(REG_ITMP3, REG_PV, disp);
4123 M_JMP(REG_ZERO, REG_ITMP3);
4128 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4130 /* everything's ok */
4136 /* createcompilerstub **********************************************************
4138 Creates a stub routine which calls the compiler.
4140 *******************************************************************************/
4142 #define COMPILERSTUB_DATASIZE 2 * SIZEOF_VOID_P
4143 #define COMPILERSTUB_CODESIZE 3 * 4
4145 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
4148 u1 *createcompilerstub(methodinfo *m)
4150 u1 *s; /* memory to hold the stub */
4152 s4 *mcodeptr; /* code generation pointer */
4154 s = CNEW(u1, COMPILERSTUB_SIZE);
4156 /* set data pointer and code pointer */
4159 s = s + COMPILERSTUB_DATASIZE;
4161 mcodeptr = (s4 *) s;
4163 /* Store the methodinfo* in the same place as in the methodheader
4164 for compiled methods. */
4166 d[0] = (ptrint) asm_call_jit_compiler;
4169 /* code for the stub */
4171 M_ALD(REG_ITMP1, REG_PV, -1 * 8); /* load methodinfo pointer */
4172 M_ALD(REG_PV, REG_PV, -2 * 8); /* load pointer to the compiler */
4173 M_JMP(REG_ZERO, REG_PV); /* jump to the compiler */
4175 #if defined(ENABLE_STATISTICS)
4177 count_cstub_len += COMPILERSTUB_SIZE;
4184 /* createnativestub ************************************************************
4186 Creates a stub routine which calls a native method.
4188 *******************************************************************************/
4190 u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
4191 registerdata *rd, methoddesc *nmd)
4193 s4 *mcodeptr; /* code generation pointer */
4194 s4 stackframesize; /* size of stackframe if needed */
4197 s4 i, j; /* count variables */
4200 s4 funcdisp; /* displacement of the function */
4202 /* initialize variables */
4205 nativeparams = (m->flags & ACC_STATIC) ? 2 : 1;
4208 /* calculate stack frame size */
4211 1 + /* return address */
4212 sizeof(stackframeinfo) / SIZEOF_VOID_P +
4213 sizeof(localref_table) / SIZEOF_VOID_P +
4214 1 + /* methodinfo for call trace */
4215 (md->paramcount > INT_ARG_CNT ? INT_ARG_CNT : md->paramcount) +
4219 /* create method header */
4221 (void) dseg_addaddress(cd, m); /* MethodPointer */
4222 (void) dseg_adds4(cd, stackframesize * 8); /* FrameSize */
4223 (void) dseg_adds4(cd, 0); /* IsSync */
4224 (void) dseg_adds4(cd, 0); /* IsLeaf */
4225 (void) dseg_adds4(cd, 0); /* IntSave */
4226 (void) dseg_adds4(cd, 0); /* FltSave */
4227 (void) dseg_addlinenumbertablesize(cd);
4228 (void) dseg_adds4(cd, 0); /* ExTableSize */
4231 /* initialize mcode variables */
4233 mcodeptr = (s4 *) cd->mcodeptr;
4236 /* generate stub code */
4238 M_LDA(REG_SP, REG_SP, -stackframesize * 8);
4239 M_AST(REG_RA, REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4242 /* call trace function */
4244 if (opt_verbosecall) {
4245 /* save integer argument registers */
4247 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4248 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4249 M_LST(rd->argintregs[i], REG_SP, j * 8);
4254 /* save and copy float arguments into integer registers */
4256 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4257 t = md->paramtypes[i].type;
4259 if (IS_FLT_DBL_TYPE(t)) {
4260 if (IS_2_WORD_TYPE(t)) {
4261 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4262 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4264 M_FST(rd->argfltregs[i], REG_SP, j * 8);
4265 M_ILD(rd->argintregs[i], REG_SP, j * 8);
4271 disp = dseg_addaddress(cd, m);
4272 M_ALD(REG_ITMP1, REG_PV, disp);
4273 M_AST(REG_ITMP1, REG_SP, 0 * 8);
4274 disp = dseg_addaddress(cd, builtin_trace_args);
4275 M_ALD(REG_PV, REG_PV, disp);
4276 M_JSR(REG_RA, REG_PV);
4277 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4278 M_LDA(REG_PV, REG_RA, -disp);
4280 for (i = 0, j = 1; i < md->paramcount && i < INT_ARG_CNT; i++) {
4281 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4282 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4287 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4288 t = md->paramtypes[i].type;
4290 if (IS_FLT_DBL_TYPE(t)) {
4291 if (IS_2_WORD_TYPE(t)) {
4292 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4294 M_FLD(rd->argfltregs[i], REG_SP, j * 8);
4301 /* get function address (this must happen before the stackframeinfo) */
4303 funcdisp = dseg_addaddress(cd, f);
4305 #if !defined(WITH_STATIC_CLASSPATH)
4307 codegen_addpatchref(cd, mcodeptr, PATCHER_resolve_native, m, funcdisp);
4309 if (opt_showdisassemble)
4314 /* save integer and float argument registers */
4316 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4317 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4318 M_LST(rd->argintregs[i], REG_SP, j * 8);
4323 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4324 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4325 M_DST(rd->argfltregs[i], REG_SP, j * 8);
4330 /* prepare data structures for native function call */
4332 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4333 M_MOV(REG_PV, rd->argintregs[1]);
4334 M_LDA(rd->argintregs[2], REG_SP, stackframesize * 8);
4335 M_ALD(rd->argintregs[3], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4336 disp = dseg_addaddress(cd, codegen_start_native_call);
4337 M_ALD(REG_PV, REG_PV, disp);
4338 M_JSR(REG_RA, REG_PV);
4339 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4340 M_LDA(REG_PV, REG_RA, -disp);
4342 /* restore integer and float argument registers */
4344 for (i = 0, j = 0; i < md->paramcount && i < INT_ARG_CNT; i++) {
4345 if (IS_INT_LNG_TYPE(md->paramtypes[i].type)) {
4346 M_LLD(rd->argintregs[i], REG_SP, j * 8);
4351 for (i = 0; i < md->paramcount && i < FLT_ARG_CNT; i++) {
4352 if (IS_FLT_DBL_TYPE(md->paramtypes[i].type)) {
4353 M_DLD(rd->argfltregs[i], REG_SP, j * 8);
4358 /* copy or spill arguments to new locations */
4360 for (i = md->paramcount - 1, j = i + nativeparams; i >= 0; i--, j--) {
4361 t = md->paramtypes[i].type;
4363 if (IS_INT_LNG_TYPE(t)) {
4364 if (!md->params[i].inmemory) {
4365 s1 = rd->argintregs[md->params[i].regoff];
4367 if (!nmd->params[j].inmemory) {
4368 s2 = rd->argintregs[nmd->params[j].regoff];
4372 s2 = nmd->params[j].regoff;
4373 M_LST(s1, REG_SP, s2 * 8);
4377 s1 = md->params[i].regoff + stackframesize;
4378 s2 = nmd->params[j].regoff;
4379 M_LLD(REG_ITMP1, REG_SP, s1 * 8);
4380 M_LST(REG_ITMP1, REG_SP, s2 * 8);
4384 if (!md->params[i].inmemory) {
4385 s1 = rd->argfltregs[md->params[i].regoff];
4387 if (!nmd->params[j].inmemory) {
4388 s2 = rd->argfltregs[nmd->params[j].regoff];
4392 s2 = nmd->params[j].regoff;
4393 if (IS_2_WORD_TYPE(t))
4394 M_DST(s1, REG_SP, s2 * 8);
4396 M_FST(s1, REG_SP, s2 * 8);
4400 s1 = md->params[i].regoff + stackframesize;
4401 s2 = nmd->params[j].regoff;
4402 M_DLD(REG_FTMP1, REG_SP, s1 * 8);
4403 if (IS_2_WORD_TYPE(t))
4404 M_DST(REG_FTMP1, REG_SP, s2 * 8);
4406 M_FST(REG_FTMP1, REG_SP, s2 * 8);
4411 /* put class into second argument register */
4413 if (m->flags & ACC_STATIC) {
4414 disp = dseg_addaddress(cd, m->class);
4415 M_ALD(rd->argintregs[1], REG_PV, disp);
4418 /* put env into first argument register */
4420 disp = dseg_addaddress(cd, _Jv_env);
4421 M_ALD(rd->argintregs[0], REG_PV, disp);
4423 /* do the native function call */
4425 M_ALD(REG_PV, REG_PV, funcdisp);
4426 M_JSR(REG_RA, REG_PV); /* call native method */
4427 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4428 M_LDA(REG_PV, REG_RA, -disp); /* recompute pv from ra */
4430 /* save return value */
4432 if (IS_INT_LNG_TYPE(md->returntype.type))
4433 M_LST(REG_RESULT, REG_SP, 0 * 8);
4435 M_DST(REG_FRESULT, REG_SP, 0 * 8);
4437 /* remove native stackframe info */
4439 M_LDA(rd->argintregs[0], REG_SP, stackframesize * 8 - SIZEOF_VOID_P);
4440 disp = dseg_addaddress(cd, codegen_finish_native_call);
4441 M_ALD(REG_PV, REG_PV, disp);
4442 M_JSR(REG_RA, REG_PV);
4443 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4444 M_LDA(REG_PV, REG_RA, -disp);
4446 /* call finished trace */
4448 if (opt_verbosecall) {
4449 /* just restore the value we need, don't care about the other */
4451 if (IS_INT_LNG_TYPE(md->returntype.type))
4452 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4454 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4456 disp = dseg_addaddress(cd, m);
4457 M_ALD(rd->argintregs[0], REG_PV, disp);
4459 M_MOV(REG_RESULT, rd->argintregs[1]);
4460 M_FMOV(REG_FRESULT, rd->argfltregs[2]);
4461 M_FMOV(REG_FRESULT, rd->argfltregs[3]);
4463 disp = dseg_addaddress(cd, builtin_displaymethodstop);
4464 M_ALD(REG_PV, REG_PV, disp);
4465 M_JSR(REG_RA, REG_PV);
4466 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4467 M_LDA(REG_PV, REG_RA, -disp);
4470 /* check for exception */
4472 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4473 disp = dseg_addaddress(cd, builtin_get_exceptionptrptr);
4474 M_ALD(REG_PV, REG_PV, disp);
4475 M_JSR(REG_RA, REG_PV);
4476 disp = (s4) ((u1 *) mcodeptr - cd->mcodebase);
4477 M_LDA(REG_PV, REG_RA, -disp);
4478 M_MOV(REG_RESULT, REG_ITMP3);
4480 disp = dseg_addaddress(cd, &_exceptionptr);
4481 M_ALD(REG_RESULT, REG_PV, disp); /* get address of exceptionptr */
4483 M_ALD(REG_ITMP1, REG_ITMP3, 0); /* load exception into reg. itmp1 */
4485 /* restore return value */
4487 if (IS_INT_LNG_TYPE(md->returntype.type))
4488 M_LLD(REG_RESULT, REG_SP, 0 * 8);
4490 M_DLD(REG_FRESULT, REG_SP, 0 * 8);
4492 M_BNEZ(REG_ITMP1, 3); /* if no exception then return */
4494 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4495 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4496 M_RET(REG_ZERO, REG_RA); /* return to caller */
4498 /* handle exception */
4500 M_AST(REG_ZERO, REG_ITMP3, 0); /* store NULL into exceptionptr */
4502 M_ALD(REG_RA, REG_SP, (stackframesize - 1) * 8); /* load return address */
4503 M_LDA(REG_ITMP2, REG_RA, -4); /* move fault address into reg. itmp2 */
4505 M_LDA(REG_SP, REG_SP, stackframesize * 8);
4507 disp = dseg_addaddress(cd, asm_handle_nat_exception);
4508 M_ALD(REG_ITMP3, REG_PV, disp); /* load asm exception handler address */
4509 M_JMP(REG_ZERO, REG_ITMP3); /* jump to asm exception handler */
4512 /* process patcher calls **************************************************/
4520 /* there can only be one <clinit> ref entry */
4521 pref = cd->patchrefs;
4523 for (pref = cd->patchrefs; pref != NULL; pref = pref->next) {
4524 /* Get machine code which is patched back in later. The call is */
4525 /* 1 instruction word long. */
4527 xcodeptr = (s4 *) (cd->mcodebase + pref->branchpos);
4528 mcode = (u4) *xcodeptr;
4530 /* patch in the call to call the following code (done at compile */
4533 tmpmcodeptr = mcodeptr; /* save current mcodeptr */
4534 mcodeptr = xcodeptr; /* set mcodeptr to patch position */
4536 M_BSR(REG_ITMP3, tmpmcodeptr - (xcodeptr + 1));
4538 mcodeptr = tmpmcodeptr; /* restore the current mcodeptr */
4540 /* create stack frame */
4542 M_LSUB_IMM(REG_SP, 6 * 8, REG_SP);
4544 /* move return address onto stack */
4546 M_AST(REG_ITMP3, REG_SP, 5 * 8);
4548 /* move pointer to java_objectheader onto stack */
4550 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
4551 /* create a virtual java_objectheader */
4553 (void) dseg_addaddress(cd, get_dummyLR()); /* monitorPtr */
4554 disp = dseg_addaddress(cd, NULL); /* vftbl */
4556 M_LDA(REG_ITMP3, REG_PV, disp);
4557 M_AST(REG_ITMP3, REG_SP, 4 * 8);
4559 M_AST(REG_ZERO, REG_SP, 4 * 8);
4562 /* move machine code onto stack */
4564 disp = dseg_adds4(cd, mcode);
4565 M_ILD(REG_ITMP3, REG_PV, disp);
4566 M_IST(REG_ITMP3, REG_SP, 3 * 8);
4568 /* move class/method/field reference onto stack */
4570 disp = dseg_addaddress(cd, pref->ref);
4571 M_ALD(REG_ITMP3, REG_PV, disp);
4572 M_AST(REG_ITMP3, REG_SP, 2 * 8);
4574 /* move data segment displacement onto stack */
4576 disp = dseg_adds4(cd, pref->disp);
4577 M_ILD(REG_ITMP3, REG_PV, disp);
4578 M_IST(REG_ITMP3, REG_SP, 1 * 8);
4580 /* move patcher function pointer onto stack */
4582 disp = dseg_addaddress(cd, pref->patcher);
4583 M_ALD(REG_ITMP3, REG_PV, disp);
4584 M_AST(REG_ITMP3, REG_SP, 0 * 8);
4586 disp = dseg_addaddress(cd, asm_wrapper_patcher);
4587 M_ALD(REG_ITMP3, REG_PV, disp);
4588 M_JMP(REG_ZERO, REG_ITMP3);
4592 codegen_finish(m, cd, (s4) ((u1 *) mcodeptr - cd->mcodebase));
4594 return m->entrypoint;
4599 * These are local overrides for various environment variables in Emacs.
4600 * Please do not remove this and leave it at the end of the file, where
4601 * Emacs will automagically detect them.
4602 * ---------------------------------------------------------------------
4605 * indent-tabs-mode: t